简体   繁体   中英

Sorting by, which is better - hashmap, treemap, custom implementation

I have an ArrayList of Subjects and they have parameter Date , I want to group them into sorted array (maybe not array, but still sorted structure) of Day objects, so every Day will have parameter Date and object will contain only subjects with this date. So the thing I wanna do is somehow group them by date and then get them. I saw implementations of grouping by using HashMap, but then I have grouped structure but not sorted, so after that I should convert this to ArrayList for example. Or maybe I should use TreeMap, which will do the same but give me back sorted structure, or maybe best way is simply write my own sorter which will get ArrayList<Subject> and return ArrayList<Day> . Also I can use LinkedHashMap which will work too

So now I have no idea what is better and what should I choose? Important thing is that most likely I will not put new values or delete values from structure, I will only get them.

UPD: If I use map then Date will be key and Day object will be value.

By saying "get them" I meant iterate through them.

All this I'm doing in order to fill my UI elements with this info so most likely I will not search something in my structure later

Here's what I think you are asking for, but hopefully my answer can help even if it's not exactly it:

  1. fast lookup using a Day as the key
  2. the result of that lookup should be sorted (ie multiple times of the same day are ordered)
  3. the possibility to see all subjects sorted by their Day

Here's one option. Use a Map that associates a Day to a sorted list of Subjects , so Map<Day, List<Subject>> . Since you don't need to add to it, you can build your mapping at the start and then sort it before you do any lookups. Here's an outline:

Map<Day, List<Subject>> buildMap(List<Subject> subjects) {
    Map<Day, List<Subject>> map = new HashMap<Day, List<Subject>>();
    // create a list of subjects for each day
    for (Subject subject : subjects) {
        if (!map.containsKey(subject.getDate().getDay())) {
            map.put(subject.getDate().getDay(), new ArrayList<Subject>());
        }
        map.get(subject.getDate().getDay()).add(subject);
    }

    // go through and sort everything now that you have grouped them
    for (Day day : map.keySet()) {
        Collections.sort(map.get(day));
    }

    return map;
}

If you also need to be able to 'get' every entry sorted throughout the map, you could maintain a sorted list of days. Like so:

List<Day> buildSortedDaysList(Map<Day, List<Subject>> map) {
    List<Day> sortedDays = new ArrayList<Day>(map.keySet());
    // again, many ways to sort, but I assume Day implements Comparable
    Collections.sort(sortedDays);
    return sortedDays;
}

You could then wrap it in a class, of which I recommend you create a better name:

class SortedMapThing {
    Map<Day, List<Subject>> map;
    List<Day> orderedDays;

    SortedMapThing(List<Subject> subjects) {
        map = buildMap(subjects);
        orderedDays = buildSortedDaysList(map);
    }

    List<Subject> getSubject(Day day) {
        return map.get(day);
    }

    List<Subject> getAllSubjects() {
        List<Subject> subjects = new ArrayList<Subject>();
        for (Day day : orderedDays) {
            subjects.addAll(map.get(day));
        }
        return subjects;
    }

}

This implementation puts the work up front and gives you efficient lookup speed. If I misunderstood your question slightly, you should be able to adjust it accordingly. If I misunderstood your question entirely...I will be sad. Cheers!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM