Встроенный div является уродцем сети и amp; должен быть избит до тех пор, пока он не станет промежутком (по крайней мере 9 раз из 10) ...
<span>foo</span>
<span>bar</span>
<span>baz</span>
... отвечает на исходный вопрос ...
На основе Collectors
документации это так же просто, как:
Map<String, Choice> result =
choices.stream().collect(Collectors.toMap(Choice::getName,
Function.identity()));
Используйте getName () как ключ и сам выбор как значение карты:
Map<String, Choice> result =
choices.stream().collect(Collectors.toMap(Choice::getName, c -> c));
choices.stream().collect(Collectors.toMap(choice -> choice.getName(),choice -> choice));
Первая функция для ключа, вторая функция для значения
– waterscar
6 January 2016 в 08:29
c -> c
, но Function.identity()
несет большую семантическую информацию. Обычно я использую статический импорт, так что я могу просто использовать identity()
– Hank D
9 April 2016 в 21:06
Вот еще один случай, если вы не хотите использовать Collectors.toMap ()
Map<String, Choice> result =
choices.stream().collect(HashMap<String, Choice>::new,
(m, c) -> m.put(c.getName(), c),
(m, u) -> {});
Collectors.toMap()
или наш собственный HashMap, как вы показали в приведенном выше примере?
– Swapnil Gangrade
18 July 2016 в 14:22
Я напишу, как преобразовать список в карту с помощью дженериков и инверсии элемента управления. Просто универсальный метод!
Возможно, у нас есть список целых чисел или список объектов. Итак, вопрос заключается в следующем: что должно быть ключом к карте?
создать интерфейс
public interface KeyFinder<K, E> {
K getKey(E e);
}
теперь с помощью инверсии управления:
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));
}
Например, если у нас есть объекты книги, этот класс должен выбрать ключ для карты
public class BookKeyFinder implements KeyFinder<Long, Book> {
@Override
public Long getKey(Book e) {
return e.getPrice()
}
}
Если вы не против использовать сторонний lib ( Vavr (ранее известный как Javaslang) ), вы можете использовать мощные новые неизменные коллекции:
// import javaslang.collection.*;
Map<String, Choice> map = list.toMap(choice -> Tuple.of(choice.getName(), choice));
Там также много методов для преобразования Java-коллекций вперед и назад.
Пожалуйста, прочитайте подробнее о новых коллекциях здесь.
Отказ от ответственности: я являюсь создателем Vavr.
Я пытался это сделать и обнаружил, что, используя ответы выше, при использовании Functions.identity()
для ключа к карте, у меня возникли проблемы с использованием локального метода, такого как this::localMethodName
, чтобы фактически работать из-за ввода вопросов .
Functions.identity()
фактически что-то делает для ввода в этом случае, поэтому метод будет работать только путем возврата Object
и принятия параметра Object
. Чтобы решить эту проблему, Я закончил тем самым Functions.identity()
и использовал s->s
.
Итак, мой код, в моем случае, чтобы перечислить все каталоги внутри каталога, и для каждого из них используйте имя каталога как ключ к карту, а затем вызвать метод с именем каталога и вернуть коллекцию элементов, выглядит так:
Map<String, Collection<ItemType>> items = Arrays.stream(itemFilesDir.listFiles(File::isDirectory))
.map(File::getName)
.collect(Collectors.toMap(s->s, this::retrieveBrandItems));
Если вы не возражаете против использования сторонних библиотек, AOL cyclops-react lib (раскрытие я являюсь вкладчиком) имеет расширения для всех типов JDK Collection , включая Список и Карта .
ListX<Choices> choices;
Map<String, Choice> map = choices.toMap(c-> c.getName(),c->c);
Для этого можно использовать потоки. Чтобы удалить необходимость явно использовать Collectors
, можно импортировать toMap
статически (как рекомендовано Effective Java, третье издание).
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));
}
Например, если вы хотите преобразовать объектные поля в карту:
Пример объекта:
class Item{
private String code;
private String name;
public Item(String code, String name) {
this.code = code;
this.name = name;
}
//getters and setters
}
И операция преобразования списка на карту:
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()));
Это можно сделать двумя способами. Пусть человек будет классом, который мы собираемся использовать для его демонстрации.
public class Person {
private String name;
private int age;
public String getAge() {
return age;
}
}
Пусть люди являются списком лиц, которые будут преобразованы в карту
1.Использование Простой foreach и лямбда-выражение в списке
Map<Integer,List<Person>> mapPersons = new HashMap<>();
persons.forEach(p->mapPersons.put(p.getAge(),p));
2. Использование коллекторов в потоке, определенных в данном списке.
Map<Integer,List<Person>> mapPersons =
persons.stream().collect(Collectors.groupingBy(Person::getAge));
Map<String,Choice> map=list.stream().collect(Collectors.toMap(Choice::getName, s->s));
Даже для этой цели,
Map<String,Choice> map= list1.stream().collect(()-> new HashMap<String,Choice>(),
(r,s) -> r.put(s.getString(),s),(r,s) -> r.putAll(s));
Еще один вариант простым способом
blockquote>Map<String,Choice> map = new HashMap<>(); choices.forEach(e->map.put(e.getName(),e));
В большинстве приведенных ответов пропустите случай, когда список имеет повторяющиеся элементы. В этом случае ответ будет кидать IllegalStateException
. См. Приведенный ниже код для обработки дубликатов списков:
public Map<String, Choice> convertListToMap(List<Choice> choices) {
return choices.stream()
.collect(Collectors.toMap(Choice::getName, choice -> choice,
(oldValue, newValue) -> newValue));
}
Если ваш ключ НЕ гарантированно уникален для всех элементов в списке, вы должны преобразовать его в Map<String, List<Choice>>
вместо Map<String, Choice>
Map<String, List<Choice>> result =
choices.stream().collect(Collectors.groupingBy(Choice::getName));
Map<String, Set<String>> collect = Arrays.asList(Locale.getAvailableLocales()).stream().collect(Collectors
.toMap(l -> l.getDisplayCountry(), l -> Collections.singleton(l.getDisplayLanguage())));
Я использую этот синтаксис
Map<Integer, List<Choice>> choiceMap =
choices.stream().collect(Collectors.groupingBy(choice -> choice.getName()));
Вот решение StreamEx
StreamEx.of(choices).toMap(Choice::getName, c -> c);
Вы можете создать поток индексов с помощью IntStream, а затем преобразовать их в Map:
Map<Integer,Item> map =
IntStream.range(0,items.size())
.boxed()
.collect(Collectors.toMap (i -> i, i -> items.get(i)));
Maps.uniqueIndex(choices, Choice::getName)
. – Bogdan Calmac 3 March 2015 в 18:59uniqueIndex()
самостоятельно в Java 8. – herman 28 August 2016 в 21:37it -> it
сам.Function.identity()
используется здесь главным образом потому, что он используется в ссылочной документации, и это все, что я знал о лямбдах во время написания – zapl 30 May 2017 в 12:57