标签: groupingby

Java 8 流将 List<Map<>> 通过相同的 <Key, Value> 分组到新的 List<Map<>>

我有一个List<Map<String,String>> 这样的:

Map<String, String> m1 = new HashMap<>();
m1.put("date", "2020.1.5");
m1.put("B", "10");

Map<String, String> m2 = new HashMap<>();
m2.put("date", "2020.1.5");
m2.put("A", "20");

Map<String, String> m3 = new HashMap<>();
m3.put("date", "2020.1.6");
m3.put("A", "30");

Map<String, String> m4 = new HashMap<>();
m4.put("date", "2020.1.7");
m4.put("C", "30");

List<Map<String, String>> before = new ArrayList<>();
before.add(m1);
before.add(m2);
before.add(m3);
before.add(m4);
Run Code Online (Sandbox Code Playgroud)

我期望的结果是生成一个新的 List 映射,该映射按 date 分组,并将同一日期中设置的所有条目放在一起,例如:

[{"A":"20","B":"10","date":"2020.1.5"},{"A":"30","date":"2020.1.6"},{"C":"30","date":"2020.1.7"}]
Run Code Online (Sandbox Code Playgroud)

我尝试了以下方法,但始终不是我期望的结果。

stream().flatmap().collect(Collectors.groupingBy())
Run Code Online (Sandbox Code Playgroud)

对这个问题的一些附加评论:

我为 LOOP 解决了这个问题,但是当列表大小约为 50000 时应用程序挂起,所以我寻求一种更好的性能方法来做到这一点。据我所知,Java 8 流平面地图可能是一种方式。所以关键不仅是重新映射这个,而且是用最高效的方式来做到这一点。

java java-8 java-stream collectors groupingby

5
推荐指数
2
解决办法
998
查看次数

Java Stream GroupBy 和Reduce

我有一个 Item 类,其中包含代码、数量和金额字段,以及可能包含许多项目(具有相同代码)的项目列表。我想按代码对项目进行分组并汇总它们的数量和金额。

我能够使用流groupingBy和实现一半的目标reduce。分组有效,但减少是将所有分组的项目减少为一个在不同代码(groupingBy键)上重复的单个项目。

不应该在此处减少减少地图中每个代码的项目列表吗?为什么它要为所有人重新调整相同的组合项目。

下面是示例代码。

import java.util.List;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.Map;

class HelloWorld {
    public static void main(String[] args) {
        List<Item> itemList = Arrays.asList(
            createItem("CODE1", 1, 12),
            createItem("CODE2", 4, 22),
            createItem("CODE3", 5, 50),
            createItem("CODE4", 2, 11),
            createItem("CODE4", 8, 20),
            createItem("CODE2", 1, 42)
        );
        
        Map<String, Item> aggregatedItems = itemList
            .stream()
            .collect(Collectors.groupingBy(
                Item::getCode,
                Collectors.reducing(new Item(), (aggregatedItem, item) -> {
                    int aggregatedQuantity = aggregatedItem.getQuantity();
                    double aggregatedAmount = aggregatedItem.getAmount();
                    
                    aggregatedItem.setQuantity(aggregatedQuantity + item.getQuantity());
                    aggregatedItem.setAmount(aggregatedAmount + item.getAmount()); …
Run Code Online (Sandbox Code Playgroud)

java reducing java-stream collectors groupingby

5
推荐指数
1
解决办法
5399
查看次数

如何在嵌套列表上使用 groupingBy

我面临一个棘手的情况,我必须在具有嵌套列表的对象上使用 groupingBy。我用 map()、flatmap()、toMap() 尝试了一些东西,但无法想出一个解决方案,只是在兜圈子。非常感谢来自流专家的任何帮助。我需要在我的 OrdersAnalyzer 类中实现 2 个方法。这是我的对象的样子:

public class Order {
  private final String id;
  private final Set<OrderLine> orderLines = new HashSet<>();
  private final Customer customer;

  //getters, setters, equals, hashcode omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)
public class OrderLine {
  private final Product product;
  private final Integer quantity;

  //getters, setters, equals, hashcode omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)
public class Product {
  private final String name;
  private final BigDecimal price;

  //getters, setters, equals, hashcode omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)
public class OrdersAnalyzer {
    /** …
Run Code Online (Sandbox Code Playgroud)

java collections java-8 java-stream groupingby

4
推荐指数
1
解决办法
122
查看次数

Java-Stream - 应用 Collector groupingBy 后将对象列表收集到一组字符串中

给定以下类OrderItem以及 s 的列表Order

@Getter
@AllArgsConstructor
@ToString
public class Order {
    String customerName;
    List<Item> items;
}

@Getter
@AllArgsConstructor
@ToString
@EqualsAndHashCode
public class Item {
    long id;
    String name;
}
Run Code Online (Sandbox Code Playgroud)

我需要创建一个映射Map<String,Set<String>> itemsByCustomerName,其中键是客户名称以及属于该客户名称Order的所有名称的一组名称。Item

输入示例:

List<Order> orders = List.of(
        new Order("John", List.of(new Item(1, "A"), new Item(2, "B"), new Item(3, "C"))),
        new Order("Alex", List.of(new Item(1, "A"), new Item(8, "H"), new Item(11, "K"))),
        new Order("John", List.of(new Item(1, "A"), new Item(6, "F"), new Item(7, "G"))),
        new …
Run Code Online (Sandbox Code Playgroud)

java java-stream collectors groupingby

3
推荐指数
1
解决办法
631
查看次数

如何在 Java 8 中使用 flatMap() 之上的收集器 groupingBy() 按属性对对象进行分组

如何创建Map<String,List<Product>> 如下。这里,String(的keyMap ) 是categorya 的Product

一种产品可以属于多个类别,如下例所示。

我正在尝试使用以下代码,但无法进行下一步操作:

products.stream()
    .flatMap(product -> product.getCategories().stream())
    . // how should I progress from here?
Run Code Online (Sandbox Code Playgroud)

结果应如下所示:

{电子=[p1,p3,p4], 时尚=[p1,p2,p4], 厨房=[p1,p2,p3], abc1=[p2], xyz1=[p3],pqr1=[p4]}

Product p1 = new Product(123, Arrays.asList("electonics,fashion,kitchen".split(",")));
Product p2 = new Product(123, Arrays.asList("abc1,fashion,kitchen".split(",")));
Product p3 = new Product(123, Arrays.asList("electonics,xyz1,kitchen".split(",")));
Product p4 = new Product(123, Arrays.asList("electonics,fashion,pqr1".split(",")));
List<Product> products = Arrays.asList(p1, p2, p3, p4);
Run Code Online (Sandbox Code Playgroud)
class Product {

    int price;
    List<String> categories;

    public Product(int price) { …
Run Code Online (Sandbox Code Playgroud)

java hashmap java-stream collectors groupingby

3
推荐指数
2
解决办法
381
查看次数

如何使用 Java 8 groupingBy 收集不同类型的列表?

我正在尝试获取类型A -> A为 的地图,并将其分组为A to List<A>. (也颠倒了键值关系,但我认为这不一定相关)。

这就是我现在所拥有的:

private static Map<Thing, List<Thing>> consolidateMap(Map<Thing, Thing> releasedToDraft) {

    // Map each draft Thing back to the list of released Things (embedded in entries)
    Map<Thing, List<Map.Entry<Thing, Thing>>> draftToEntry = releasedToDraft.entrySet().stream()
            .collect(groupingBy(
                    Map.Entry::getValue,
                    toList()
            ));

    // Get us back to the map we want (Thing to list of Things)
    return draftToEntry.entrySet().stream()
            .collect(toMap(
                    Map.Entry::getKey,
                    ThingReleaseUtil::entriesToThings
            ));
}

private static List<Thing> entriesToThings(Map.Entry<Thing, List<Map.Entry<Thing, Thing>>> entry) {
    return entry.getValue().stream()
            .map(Map.Entry::getKey)
            .collect(toList());
}
Run Code Online (Sandbox Code Playgroud)

我想在单个语句中执行此操作,并且我觉得必须可以将 …

java reducing java-8 groupingby

2
推荐指数
1
解决办法
141
查看次数

在单循环中以声明方式单独按多个字段进行 Java 流分组

我用谷歌搜索了它,但我主要找到了按聚合字段分组或更改流响应的案例,但不是以下场景:

我有一个User带有字段categorymarketingChannel.

我必须以声明式风格编写一个方法,该方法接受用户列表并基于category和基于marketingChannel单独(即 not groupingBy(... ,groupingBy(..)))计算用户 。

我无法在一个循环中完成。这是我必须达到的目标。

我编码了一些方法如下:

import java.util.*;
import java.util.stream.*;
public class Main
{
    public static void main(String[] args) {
        List<User> users = User.createDemoList();
        imperative(users);
        declerativeMultipleLoop(users);
        declerativeMultipleColumn(users);
    }
    
    public static void imperative(List<User> users){
        Map<String, Integer> categoryMap = new HashMap<>();
        Map<String, Integer> channelMap = new HashMap<>();
        for(User user : users){
           Integer  value = categoryMap.getOrDefault(user.getCategory(), 0);
           categoryMap.put(user.getCategory(), value+1);
           value = channelMap.getOrDefault(user.getMarketingChannel(), 0);
           channelMap.put(user.getMarketingChannel(), value+1);
        }
        System.out.println("imperative");
        System.out.println(categoryMap);
        System.out.println(channelMap); …
Run Code Online (Sandbox Code Playgroud)

java declarative-programming java-stream groupingby

2
推荐指数
1
解决办法
69
查看次数

使用流分组时将字符串分为多个组

我正在尝试做的事情的简化示例:

假设我有一个字符串列表,需要根据是否包含特定子字符串的条件将其分为 4 组。如果一个字符串包含Foo它应该属于该组FOO,如果它包含Bar它应该属于该组BAR,如果它包含两者它应该出现在两个组中。

List<String> strings = List.of("Foo", "FooBar", "FooBarBaz", "XXX");
Run Code Online (Sandbox Code Playgroud)

由于字符串被分组到第一个匹配组中,因此上述输入的简单方法无法按预期工作:

Map<String,List<String>> result1 =
strings.stream()
        .collect(Collectors.groupingBy(
                        str -> str.contains("Foo") ? "FOO" :
                                    str.contains("Bar") ? "BAR" :
                                            str.contains("Baz") ? "BAZ" : "DEFAULT"));
Run Code Online (Sandbox Code Playgroud)

结果1是

{FOO=[Foo, FooBar, FooBarBaz], DEFAULT=[XXX]}
Run Code Online (Sandbox Code Playgroud)

期望的结果应该是

{FOO=[Foo, FooBar, FooBarBaz], BAR=[FooBar, FooBarBaz], BAZ=[FooBarBaz], DEFAULT=[XXX]}
Run Code Online (Sandbox Code Playgroud)

经过一段时间的搜索,我找到了另一种方法,它接近我想要的结果,但不太完全

Map<String,List<String>> result2 =
List.of("Foo", "Bar", "Baz", "Default").stream()
        .flatMap(str -> strings.stream().filter(s -> s.contains(str)).map(s -> new String[]{str.toUpperCase(), s}))
        .collect(Collectors.groupingBy(arr -> arr[0], Collectors.mapping(arr -> arr[1], Collectors.toList())));

System.out.println(result2);
Run Code Online (Sandbox Code Playgroud)

结果2是

{BAR=[FooBar, …
Run Code Online (Sandbox Code Playgroud)

java hashmap java-stream groupingby

2
推荐指数
2
解决办法
613
查看次数