2017-11-22 107 views
6

Mam listę map, jak poniżej. Chcę posortować mapy na liście w kolejności niestandardowej w języku Java 8.Niestandardowe rodzaje map w języku Java 8

Na przykład poniżej znajduje się lista map.

[{model=Ferrari}, 
{model=Tesla}, 
{model=Benz}, 
{model=Honda}] 

Gdybym sortować powyższą listę map z użyciem poniższego kodu, jego sortowanie alfabetyczne.

l.sort(Comparator.comparing((Map<String,String> mp) -> mp.get("model"))); 

podaje dane wyjściowe poniżej.

[{Model = Benz}, {Model = Ferrari}, {Model = Honda}, {Model = Tesla}]

Ale muszę uporządkować tę mapę na podstawie kolejności (nie Porządek alfabetyczny): Honda, Tesla, Benz, Ferrari

Czy istnieje lepsze podejście, które możemy osiągnąć sortowanie niestandardowe w Java 8?

+0

Jeśli chcesz zlecenia niestandardowe, musi być zdefiniowana gdzieś. Możesz na przykład dodać drugi wpis do każdej z map, "order = 1" lub coś podobnego. –

+3

Jeśli umieścisz '[" Honda "," Tesla "," Benz "," Ferrari "]' na liście, możesz sortować według indeksu modelu na tej liście. – khelwood

+0

@khelwood to dobry pomysł. Pozwól, że wypróbuję Twoją sugestię. –

Odpowiedz

6

Powinieneś zdefiniować preferowaną kolejność gdzieś poza tym kodem. Umieść go na jakiejś liście, a następnie przekształć na Mapę modelname -> indeks.

Map<String,Integer> modelOrder = ..... 

Następnie można dodać jeszcze jedno wyszukiwanie do uzyskania liczby porządkowej dla porównania.

l.sort(Comparator.comparing((Map<String,String> mp) -> 
    modelOrder.get(mp.get("model")))); 

To eksploduje w twarz, jeśli nieznany model kiedykolwiek napotkany. Można to zrobić szybko naprawić coś jak

l.sort(Comparator.comparing((Map<String,String> mp) -> 
    modelOrder.getOrDefault(mp.get("model"),Integer.MAX_VALUE))); 

umieścić nieznanych modeli na samym końcu, ale nie będą one klasyfikowane między sobą (tak, nawet sama nieznany wzór może być przeplatane przez innych nieznanych).

Edit:

Jak ludzie sugerowane w komentarzach, to może być rozwiązane ładnie z .thenComparing

l.sort(Comparator 
    .comparing((Map<String,String> mp) -> modelOrder.getOrDefault(mp.get("model"),Integer.MAX_VALUE)) 
    .thenComparing((Map<String,String> mp) -> mp.get("model"))); 
+1

Powinien być w stanie użyć czegoś takiego jak '(long) (Math.abs (mp.get (" model "). hashCode())) + modelOrder.size() 'jako domyślna wartość sortowania nieznanych. Długie użycie ma zapobiec przepełnieniu kodu hashcode, a modelOrder.size() powinien upewnić się, że jest po znanych modelach. Ogólnie może to być nieco przesada – phflack

+0

Lub po prostu użyj 'thenComparing (modelOrder.get (mp.get (" model "))', aby porównać ciągi, jeśli nie znajdują się na liście (po porównaniu 'getOrDefault()'). –

+0

@Didier L: możesz uniknąć dodatkowego wyszukiwania na mapie, 'Comparator.comparing (mp -> mp.get (" model "), Komparator.comparingInt ((String s) -> modelOrder.getOrDefault (s, Integer.MAX_VALUE)). thenComparing (Comparator.naturalOrder())) – Holger

Powiązane problemy