#java #java-stream
Вопрос:
Я хочу преобразовать список SimpleEntry<String, Product>
в a Map<String, List<Product>
. Строка-это название бренда, и у каждого названия бренда есть продукты. Итак, я хочу преобразовать List<SimpleEntry<>
в Map<String, List<Product>
то место на карте, где я получаю список продуктов для названия бренда.
В настоящее время я использую следующий код, но я думаю, что это можно сделать и с потоками
//List<AbstractMap.SimpleEntry<String, Product>> listOfSimpleEntries = new ArrayList<>() is a list of simple Entries
//e.g.
//nike, productA
//adidas, productB,
//nike, productC
Map<String, List<Product>> brandToProductsMap = new HashMap<>();
for (AbstractMap.SimpleEntry<String, Product> simpleEntry : listOfSimpleEntries) {
if (!brandToProductsMap.containsKey(simpleEntry.getKey())) {
brandToProductsMap.put(simpleEntry.getKey(), new ArrayList<>());
}
brandToProductsMap.get(simpleEntry.getKey()).add(simpleEntry.getValue());
}
Я попытался заменить приведенный выше код потоками, как показано ниже, но я получаю java.util.Список массивов не может быть приведен к продукту
Map<String, List<Product>> brandToProductsMap = listOfSimpleEntries.stream().collect(Collectors.groupingBy(
w -> w.getKey(), Collectors.mapping(x -> x.getValue(), Collectors.toList())));
Может кто-нибудь, пожалуйста, указать мне, чего мне здесь не хватает? Спасибо.
Редактировать 2 Код, который я написал, работает как отдельная программа, но не является частью проекта. Я обнаружил, что в целевой папке код скомпилирован, как показано ниже, что кажется неправильным.
Map<String, List<Product>> brandToProductsMap = (Map)listOfSimpleEntries.stream().collect(Collectors.groupingBy((w) -> {
return (String)w.getKey();
}, Collectors.mapping((x) -> {
return (Product)x.getValue();
}, Collectors.toList())));
Iterator var5 = brandToProductsMap .entrySet().iterator();
Комментарии:
1. предполагая
CompatibleProduct
, что это опечаткаProduct
, это невозможно воспроизвести.2. Да, это была опечатка. Спасибо, что указали на это.
Ответ №1:
Вы можете сделать:
List<AbstractMap.SimpleEntry<String, Product>> entries = Arrays.asList(
new AbstractMap.SimpleEntry<>("Nike", new Product("ProductA")),
new AbstractMap.SimpleEntry<>("Adidas", new Product("ProductB")),
new AbstractMap.SimpleEntry<>("Nike", new Product("ProductC"))
);
Map<String, List<Product>> brandNameToProduct = entries.stream()
.collect(Collectors.groupingBy(e -> e.getKey(),
Collectors.mapping(e -> e.getValue(), Collectors.toList())));
System.out.println(brandNameToProduct);
Выход:
{Nike=[Product(name=ProductA), Product(name=ProductC)], Adidas=[Product(name=ProductB)]}
Редактировать:
Я думаю, что ты поступил точно так же, как и я, так что, возможно, твоя идея сошла с ума.
Комментарии:
1. Да, я сделал точно то же самое, и если я запущу его как отдельную программу, он будет работать нормально, но не как часть проекта. Я не знаю, в чем проблема с моим интеллектом.
Ответ №2:
Надеюсь, что приведенный ниже фрагмент кода может помочь:
public static void main(String[] args) {
List<SimpleEntry<String, Product>> list = new ArrayList<SimpleEntry<String, Product>>();
list.add(SimpleEntry.of("electronic", new Product(1, "SmartPhone")));
list.add(SimpleEntry.of("electronic", new Product(2, "Laptop")));
list.add(SimpleEntry.of("office", new Product(3, "Book")));
list.add(SimpleEntry.of("office", new Product(4, "Pencil")));
list.add(SimpleEntry.of("office", new Product(5, "Notes")));
list.add(SimpleEntry.of("garden", new Product(6, "Rosesmany")));
list.add(SimpleEntry.of("garden", new Product(7, "Soil Mix")));
list.add(SimpleEntry.of("garden", new Product(8, "Pressure Sprayer")));
System.out.println("Before:");
list.stream().forEach(System.out::println);
Map<String, List<Product>> map = list.stream().collect(
groupingBy(entry -> entry.getKey(), mapping(entry -> entry.getEntry(), toList()))
);
System.out.println("After:");
map.forEach((k, v) -> System.out.println("Key : " k ", Value : " v));
}
Простой вход
public class SimpleEntry<K, V> {
private K key;
private V entry;
static public <K, V> SimpleEntry<K, V> of (K key, V entry)
{
SimpleEntry<K, V> sEntry = new SimpleEntry<>();
sEntry.setKey(key);
sEntry.setEntry(entry);
return sEntry;
}
//getters/setters...
}
Я написал это, и это сработало для меня:
Before:
electronic - Product(1, SmartPhone)
electronic - Product(2, Laptop)
office - Product(3, Book)
office - Product(4, Pencil)
office - Product(5, Notes)
garden - Product(6, Rosesmany)
garden - Product(7, Soil Mix)
garden - Product(8, Pressure Sprayer)
After:
Key : electronic, Value : [Product(1, SmartPhone), Product(2, Laptop)]
Key : garden, Value : [Product(6, Rosesmany), Product(7, Soil Mix), Product(8, Pressure Sprayer)]
Key : office, Value : [Product(3, Book), Product(4, Pencil), Product(5, Notes)]
Комментарии:
1. Спасибо, Хоуи. Ваш код работает и мой, и тот, который добавлен наиболее нужным кроликом, тоже работает при выполнении в отдельном классе, но в рамках проекта я получаю сообщение об ошибке. Итак, я пытаюсь выяснить, какие настройки мне нужно изменить, чтобы сделать это правильным.