Chcę przetłumaczyć listę obiektów na mapę przy użyciu strumieni i lambd Java 3.
Tak napisałbym to w Javie 7 i niższych.
private Map<String, Choice> nameMap(List<Choice> choices) {
final Map<String, Choice> hashMap = new HashMap<>();
for (final Choice choice : choices) {
hashMap.put(choice.getName(), choice);
}
return hashMap;
}
Mogę to łatwo osiągnąć za pomocą Java 8 i Guava, ale chciałbym wiedzieć, jak to zrobić bez Guava.
W Guava:
private Map<String, Choice> nameMap(List<Choice> choices) {
return Maps.uniqueIndex(choices, new Function<Choice, String>() {
@Override
public String apply(final Choice input) {
return input.getName();
}
});
}
I Guawa z lambdami Java 8.
private Map<String, Choice> nameMap(List<Choice> choices) {
return Maps.uniqueIndex(choices, Choice::getName);
}
java
lambda
java-8
java-stream
Tom Cammann
źródło
źródło
Maps.uniqueIndex(choices, Choice::getName)
.Seq
z biblioteki JOOL (którą poleciłbym każdemu, kto używa Java 8), możesz również poprawić zwięzłość dzięki:seq(choices).toMap(Choice::getName)
it -> it
siebie.Function.identity()
jest tu używany głównie dlatego, że jest używany w przywołanej dokumentacji i to wszystko, co wiedziałem o lambdach w czasie pisaniaJeśli NIE gwarantujesz, że Twój klucz będzie unikalny dla wszystkich elementów na liście, powinieneś go przekonwertować na
Map<String, List<Choice>>
zamiastMap<String, Choice>
źródło
Multimaps
metoda guawy jest lepszą opcją? Może to być niedogodność, ponieważ nie zwracaMap
przedmiotu.Użyj
getName()
jako klucza iChoice
jako wartości mapy:źródło
Collectors.toMap(Choice::getName,c->c)
(2 znaki krótsze)choices.stream().collect(Collectors.toMap(choice -> choice.getName(),choice -> choice));
Pierwszej funkcji dla klucza, drugiej funkcji dla wartościc -> c
aleFunction.identity()
zawiera więcej informacji semantycznych. Zwykle używam importu statycznego, więc mogę po prostu użyćidentity()
Oto kolejna w przypadku, gdy nie chcesz używać Collectors.toMap ()
źródło
Collectors.toMap()
lub naszej własnej HashMap, jak pokazano w powyższym przykładzie?Większość wymienionych odpowiedzi nie zawiera przypadku, gdy lista zawiera zduplikowane elementy . W takim przypadku pojawi się odpowiedź
IllegalStateException
. Zapoznaj się z poniższym kodem, aby obsługiwać również duplikaty list :źródło
źródło
Na przykład, jeśli chcesz przekonwertować pola obiektów na mapę:
Przykładowy obiekt:
I operacja przekształca Listę na mapę:
źródło
Jeśli nie przeszkadza przy użyciu bibliotek 3rd party, AOL Cyklop reagują lib (ujawnienie jestem specjalista) posiada rozszerzenia dla wszystkich JDK Kolekcja typów, w tym listy i mapą .
źródło
Próbowałem to zrobić i odkryłem, że korzystając z powyższych odpowiedzi, używając
Functions.identity()
klucza do mapy, miałem problemy z używaniem metody lokalnej, takiej jakthis::localMethodName
faktyczna praca z powodu problemów z pisaniem.Functions.identity()
faktycznie robi coś z pisaniem w tym przypadku, więc metoda zadziałałaby tylko przez zwrócenieObject
i zaakceptowanie parametruObject
Aby rozwiązać ten problem, skończyłem porzucając
Functions.identity()
i używającs->s
zamiast tego.Tak więc mój kod, w moim przypadku do wyświetlenia wszystkich katalogów w katalogu, i dla każdego z nich użyj nazwy katalogu jako klucza do mapy, a następnie wywołaj metodę z nazwą katalogu i zwróć kolekcję elementów, wygląda następująco:
źródło
Możesz utworzyć Strumień indeksów za pomocą IntStream, a następnie przekonwertować je na mapę:
źródło
Napiszę, jak przekonwertować listę na mapę za pomocą ogólnych i inwersji kontroli . Po prostu uniwersalna metoda!
Może mamy listę liczb całkowitych lub listę obiektów. Pytanie brzmi zatem: co powinno być kluczem do mapy?
utwórz interfejs
teraz używając odwrócenia kontroli:
Na przykład, jeśli mamy obiekty książki, ta klasa ma wybrać klucz do mapy
źródło
Używam tej składni
źródło
groupingBy
tworzy, aMap<K,List<V>>
nieMap<K,V>
.String getName();
(nie Integer)źródło
Można to zrobić na 2 sposoby. Niech osoba będzie klasą, której użyjemy, aby to zademonstrować.
Niech osoby będą listą Osób, które zostaną przekonwertowane na mapę
1.Za pomocą prostego foreach i wyrażenia lambda na liście
2.Używanie kolektorów w strumieniu zdefiniowanych na danej liście.
źródło
W tym celu można użyć strumieni. Aby usunąć potrzebę jawnego używania
Collectors
, można importowaćtoMap
statycznie (zgodnie z zaleceniami Effective Java, wydanie trzecie).źródło
Oto rozwiązanie StreamEx
źródło
Nawet mi to służy,
źródło
Jeśli należy zastąpić każdą nową wartość dla tej samej nazwy klucza:
Jeśli wszystkie opcje muszą być pogrupowane na liście dla nazwy:
źródło
źródło
Jako alternatywę
guava
można zastosować kotlin-stdlibźródło
Dubluj klucz AA {12 = ASDFASDFASDF, 7 = EEDDDAD, 4 = CCCC, 3 = BBB, 2 = AA}
źródło