1. Introduktion
I den här snabbhandboken lär vi oss att sortera en HashMap i Java .
Mer specifikt tittar vi på att sortera HashMap- poster efter deras nyckel eller värde med hjälp av:
- TreeMap
- ArrayList and Collections.sort ()
- TreeSet
- Använda Stream API , och slutligen
- Använda Guava- biblioteket
2. Använda en TreeMap
Som vi vet sorteras nycklarna i TreeMap efter deras naturliga ordning . Detta är en bra lösning när vi vill sortera nyckel-värdeparen efter deras nyckel. Så idén är att trycka all data från vår HashMap in i TreeMap .
Till att börja med, låt oss definiera en HashMap och initiera den med lite data:
Map map = new HashMap(); Employee employee1 = new Employee(1L, "Mher"); map.put(employee1.getName(), employee1); Employee employee2 = new Employee(22L, "Annie"); map.put(employee2.getName(), employee2); Employee employee3 = new Employee(8L, "John"); map.put(employee3.getName(), employee3); Employee employee4 = new Employee(2L, "George"); map.put(employee4.getName(), employee4);
För Employee klass, notera att vi har implementerat Jämförbar :
public class Employee implements Comparable { private Long id; private String name; // constructor, getters, setters // override equals and hashCode @Override public int compareTo(Employee employee) { return (int)(this.id - employee.getId()); } }
Därefter lagrar vi posterna i TreeMap med hjälp av dess konstruktör:
TreeMap sorted = new TreeMap(map);
Eller putAll- metoden för att kopiera data:
TreeMap sorted = new TreeMap(); sorted.putAll(map);
Och det är allt! För att säkerställa att våra kartposter sorteras efter nyckel, låt oss skriva ut dem:
Annie=Employee{id=22, name="Annie"} George=Employee{id=2, name="George"} John=Employee{id=8, name="John"} Mher=Employee{id=1, name="Mher"}
Som vi ser sorteras nycklarna i naturlig ordning.
3. Använda ArrayList
Naturligtvis kan vi sortera posterna på kartan med hjälp av ArrayList . Huvudskillnaden från den tidigare metoden är att vi inte underhåller Map- gränssnittet här .
3.1. Sortera efter nyckel
Låt oss ladda nyckeluppsättningen i en ArrayList :
List employeeByKey = new ArrayList(map.keySet()); Collections.sort(employeeByKey);
Och resultatet är:
[Annie, George, John, Mher]
3.2. Sortera efter värde
Tänk nu om vi vill sortera våra kartvärden efter id- fältet för anställdsobjekt ? Vi kan också använda en ArrayList för det.
Låt oss först kopiera värdena till listan:
List employeeById = new ArrayList(map.values());
Och efter det sorterar vi det:
Collections.sort(employeeById);
Kom ihåg att detta fungerar eftersom anställd implementerar det jämförbara gränssnittet . Annars skulle vi behöva definiera en manuell komparator för vårt samtal till Collections.sort .
För att kontrollera resultaten skriver vi ut medarbetarenById :
[Employee{id=1, name="Mher"}, Employee{id=2, name="George"}, Employee{id=8, name="John"}, Employee{id=22, name="Annie"}]
Som vi ser sorteras objekten efter deras id- fält.
4. Använda en TreeSet
Om vi inte vill acceptera dubbla värden i vår sorterade samling finns det en trevlig lösning med TreeSet.
Låt oss först lägga till några dubbletter till vår ursprungliga karta:
Employee employee5 = new Employee(1L, "Mher"); map.put(employee5.getName(), employee5); Employee employee6 = new Employee(22L, "Annie"); map.put(employee6.getName(), employee6);
4.1. Sortera efter nyckel
För att sortera kartan efter dess nyckelposter:
SortedSet keySet = new TreeSet(map.keySet());
Låt oss skriva ut keySet och se utdata:
[Annie, George, John, Mher]
Nu har vi karttangenterna sorterade utan dubbletter.
4.2. Sortera efter värde
På samma sätt ser konverteringskoden ut för kartvärdena:
SortedSet values = new TreeSet(map.values());
Och resultaten är:
[Employee{id=1, name="Mher"}, Employee{id=2, name="George"}, Employee{id=8, name="John"}, Employee{id=22, name="Annie"}]
Som vi kan se finns det inga dubbletter i utdata. Detta fungerar med anpassade objekt när vi åsidosätter lika och hashCode.
5. Använda Lambdas och Streams
Sedan Java 8 kan vi använda Stream API och lambda-uttryck för att sortera kartan . Allt vi behöver är att kalla sorterad metoden över kartans strömmen pipeline.
5.1. Sortera efter nyckel
För att sortera efter nyckel använder vi jämförandeByKey- komparatorn:
map.entrySet() .stream() .sorted(Map.Entry.comparingByKey()) .forEach(System.out::println);
De slutliga forEach scen skriver ut resultaten:
Annie=Employee{id=22, name="Annie"} George=Employee{id=2, name="George"} John=Employee{id=8, name="John"} Mher=Employee{id=1, name="Mher"}
Som standard är sorteringsläget stigande.
5.2. Sortera efter värde
Naturligtvis kan vi också sortera efter anställdens objekt:
map.entrySet() .stream() .sorted(Map.Entry.comparingByValue()) .forEach(System.out::println);
As we see, the code above prints out a map sorted by the id fields of Employee objects:
Mher=Employee{id=1, name="Mher"} George=Employee{id=2, name="George"} John=Employee{id=8, name="John"} Annie=Employee{id=22, name="Annie"}
Additionally, we can collect the results into a new map:
Map result = map.entrySet() .stream() .sorted(Map.Entry.comparingByValue()) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
Note that we collected our results into a LinkedHashMap. By default, Collectors.toMap returns a new HashMap, but as we know, HashMap doesn't guarantee iterationorder, while LinkedHashMap does.
6. Using Guava
Lastly, a library that allows us to sort the HashMap is Guava. Before we start, it'll be useful to check our write-up about maps in Guava.
Låt oss först förklara en beställning eftersom vi vill sortera vår karta efter anställds ID- fält:
Ordering naturalOrdering = Ordering.natural() .onResultOf(Functions.forMap(map, null));
Nu är allt vi behöver använda ImmutableSortedMap för att illustrera resultaten:
ImmutableSortedMap.copyOf(map, naturalOrdering);
Och återigen är utdata en karta ordnad av id- fältet:
Mher=Employee{id=1, name="Mher"} George=Employee{id=2, name="George"} John=Employee{id=8, name="John"} Annie=Employee{id=22, name="Annie"}
7. Sammanfattning
I den här artikeln granskade vi ett antal sätt att sortera en HashMap efter nyckel eller värde.
Och vi tittade närmare på hur vi kan göra detta när attributet är en anpassad klass genom att implementera Comparable .
Slutligen, som alltid, kan koden som används under diskussionen hittas på GitHub.