Java 8 lista na mapie
Chcę przetłumaczyć listę obiektów na mapę używając strumieni Java 8 i Lambda.
Tak bym to napisał w Javie 7 i poniżej.
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 Guawie:
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 Java 8 lambda.
private Map<String, Choice> nameMap(List<Choice> choices) {
return Maps.uniqueIndex(choices, Choice::getName);
}
17 answers
Na podstawie Collectors
Dokumentacja to tak proste jak:
Map<String, Choice> result =
choices.stream().collect(Collectors.toMap(Choice::getName,
Function.identity()));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-11 15:17:11
Jeśli twój klucz jest , a nie gwarantowany, że będzie unikalny dla wszystkich elementów listy, powinieneś przekonwertować go na Map<String, List<Choice>>
zamiast Map<String, Choice>
Map<String, List<Choice>> result =
choices.stream().collect(Collectors.groupingBy(Choice::getName));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-30 00:05:59
Użyj getName () jako klucza i samego wyboru jako wartości Mapy:
Map<String, Choice> result =
choices.stream().collect(Collectors.toMap(Choice::getName, c -> c));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-10 10:41:13
Tutaj jest jeszcze jeden, jeśli nie chcesz używać kolektorów.toMap ()
Map<String, Choice> result =
choices.stream().collect(HashMap<String, Choice>::new,
(m, c) -> m.put(c.getName(), c),
(m, u) -> {});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-19 18:38:37
Jeszcze jedna opcja w prosty sposób
Map<String,Choice> map = new HashMap<>();
choices.forEach(e->map.put(e.getName(),e));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-07 07:02:40
Jeśli nie masz nic przeciwko używaniu bibliotek stron trzecich, lib cyclops-react AOL (disclosure I am a contributor) ma rozszerzenia dla wszystkich typów JDK Collection, w tym List i Map.
ListX<Choices> choices;
Map<String, Choice> map = choices.toMap(c-> c.getName(),c->c);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-24 17:45:07
Na przykład, jeśli chcesz przekonwertować pola obiektu na mapę:
Przykładowy obiekt:
class Item{
private String code;
private String name;
public Item(String code, String name) {
this.code = code;
this.name = name;
}
//getters and setters
}
I operacja Konwertuj listę na mapę:
List<Item> list = new ArrayList<>();
list.add(new Item("code1", "name1"));
list.add(new Item("code2", "name2"));
Map<String,String> map = list.stream()
.collect(Collectors.toMap(Item::getCode(), Item::getName()));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-20 13:06:07
Próbowałem to zrobić i stwierdziłem, że używając powyższych odpowiedzi, podczas używania {[1] } dla klucza do mapy, miałem problemy z używaniem lokalnej metody, takiej jak this::localMethodName
, aby faktycznie działać z powodu problemów z wpisaniem.
Functions.identity()
w rzeczywistości robi coś z typowaniem w tym przypadku, więc metoda działa tylko przez zwrócenie Object
i zaakceptowanie param Object
Functions.identity()
i zamiast tego użyłem s->s
.
Więc mój kod, w moim przypadku do listy wszystkich katalogów wewnątrz 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:
Map<String, Collection<ItemType>> items = Arrays.stream(itemFilesDir.listFiles(File::isDirectory))
.map(File::getName)
.collect(Collectors.toMap(s->s, this::retrieveBrandItems));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-08 10:43:55
Większość z wymienionych odpowiedzi pomija przypadek, gdy lista ma duplikaty pozycji . W takim przypadku odpowiedź rzuci IllegalStateException
. Zobacz poniższy kod , aby również obsługiwać duplikaty listy :
public Map<String, Choice> convertListToMap(List<Choice> choices) {
return choices.stream()
.collect(Collectors.toMap(Choice::getName, choice -> choice,
(oldValue, newValue) -> newValue));
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-17 06:45:35
Możesz utworzyć strumień indeksów za pomocą strumienia IntStream, a następnie przekonwertować je na mapę:
Map<Integer,Item> map =
IntStream.range(0,items.size())
.boxed()
.collect(Collectors.toMap (i -> i, i -> items.get(i)));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-09 05:33:11
Używam tej składni
Map<Integer, List<Choice>> choiceMap =
choices.stream().collect(Collectors.groupingBy(choice -> choice.getName()));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-24 19:31:05
Map<String, Set<String>> collect = Arrays.asList(Locale.getAvailableLocales()).stream().collect(Collectors
.toMap(l -> l.getDisplayCountry(), l -> Collections.singleton(l.getDisplayLanguage())));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-24 16:55:43
Możliwe jest użycie strumieni do tego celu. Aby usunąć potrzebę jawnego używania Collectors
, można zaimportować toMap
statycznie (zgodnie z zaleceniami Effective Java, third edition).
import static java.util.stream.Collectors.toMap;
private static Map<String, Choice> nameMap(List<Choice> choices) {
return choices.stream().collect(toMap(Choice::getName, it -> it));
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-02 12:05:36
Napiszę jak przekonwertować listę na mapę używając generykówi inwersji sterowania. Po prostu uniwersalna metoda!
Może mamy listę liczb całkowitych lub listę obiektów . więc pytanie brzmi: jaki powinien być klucz mapy?
Utwórz interfejs
public interface KeyFinder<K, E> {
K getKey(E e);
}
Teraz za pomocą inwersji sterowania:
static <K, E> Map<K, E> listToMap(List<E> list, KeyFinder<K, E> finder) {
return list.stream().collect(Collectors.toMap(e -> finder.getKey(e) , e -> e));
}
Na przykład, jeśli mamy obiekty książki, klasa ta ma wybrać klucz dla mapy
public class BookKeyFinder implements KeyFinder<Long, Book> {
@Override
public Long getKey(Book e) {
return e.getPrice()
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-14 00:59:37
Oto rozwiązanie przez StreamEx
StreamEx.of(choices).toMap(Choice::getName, c -> c);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-09 03:51:27
Map<String,Choice> map=list.stream().collect(Collectors.toMap(Choice::getName, s->s));
Nawet służy temu celowi dla mnie,
Map<String,Choice> map= list1.stream().collect(()-> new HashMap<String,Choice>(),
(r,s) -> r.put(s.getString(),s),(r,s) -> r.putAll(s));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-26 01:52:16
Można to zrobić na dwa sposoby. Niech osoba będzie klasą, której będziemy używać, aby ją zademonstrować.
public class Person {
private String name;
private int age;
public String getAge() {
return age;
}
}
Let person be the list of Persons to be converted to the map
1.Użycie prostego foreach i wyrażenia Lambda na liście
Map<Integer,List<Person>> mapPersons = new HashMap<>();
persons.forEach(p->mapPersons.put(p.getAge(),p));
2.Korzystanie z kolektorów w Strumieniu zdefiniowanym na podanej liście.
Map<Integer,List<Person>> mapPersons =
persons.stream().collect(Collectors.groupingBy(Person::getAge));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-04 10:45:05