标签: collectors

Java - groupingBy with collectingAndThen - 是否有更快/更好/更清洁的方式?

我有以下课程(有getter):

public class AlgorithmPrediction {
    private final String algorithmName;
    private final Map<BaseDatabaseProduct, Double> productsToAccuracy;
}
Run Code Online (Sandbox Code Playgroud)

现在我想从一个由AlgorithmPrediction对象填充的集合中创建一个映射,其中algorithmName (唯一)作为键和productsToAccuracy值.我想不出比这更复杂的东西:

algorithmPredictions.stream()
.collect(
        groupingBy(
                AlgorithmPrediction::getAlgorithmName,
                Collectors.collectingAndThen(
                        toSet(),
                        s -> s.stream().map(AlgorithmPrediction::getProductsToAccuracy).collect(toSet())
                )
        )
);
Run Code Online (Sandbox Code Playgroud)

这不可能是对的.我错过了什么?谢谢!

java lambda grouping java-8 collectors

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

Java 8 - 在地图值中过滤列表

我正在编写一个方法,它接受在这里定义a Map的形式的输入.Map<Term, List<Integer>>Term

方法:

  1. 翻过它的键Map并使用Term属性过滤它们.
  2. 对于每个剩余的键,获取相应列表的大小,将其限制为5(min(List.size(), 5))并将输出添加到全局变量(例如totalSum)
  3. 返回 totalSum

这是我到目前为止所写的:

 inputMap
    .entrySet()
    .stream()
    .filter(entry -> entry.getKey().field().equals(fieldName))    // Keep only terms with fieldName
    .forEach(entry -> entry.getValue()
        .map(size -> Math.min(entry.getValue().size(), 5)))   // These 2 lines do not work
        .sum();
Run Code Online (Sandbox Code Playgroud)

我无法将列表流作为输入,为每个列表输出一个整数并返回所有输出的总和.

我显然可以使用for循环来编写它,但我正在尝试学习Java 8,并且好奇如果使用它可以解决这个问题.

java iterator java-8 java-stream collectors

6
推荐指数
1
解决办法
1416
查看次数

如何使用java 8将二维对象Set/ArrayList转换为一个Flat Set/List

我是java 8中的新手,我有Set of Set例如:

Set<Set<String>> aa = new HashSet<>();
Set<String> w1 = new HashSet<>();

w1.add("1111");
w1.add("2222");
w1.add("3333");

Set<String> w2 = new HashSet<>();
w2.add("4444");
w2.add("5555");
w2.add("6666");

Set<String> w3 = new HashSet<>();
w3.add("77777");
w3.add("88888");
w3.add("99999");

aa.add(w1);
aa.add(w2);
aa.add(w3);
Run Code Online (Sandbox Code Playgroud)

预期结果:平板设置...类似于:

但它不起作用!

// HERE I WANT To Convert into FLAT Set 
// with the best PERFORMANCE !!
Set<String> flatSet = aa.stream().flatMap(a -> setOfSet.stream().flatMap(ins->ins.stream().collect(Collectors.toSet())).collect(Collectors.toSet()));
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

java java-8 java-stream collectors

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

Collectors.toMap具有相同的键(打印相同的键)

我有这个代码来获取地图:

List<MyObject> myList = myMethod.getList();
myList.stream().collect(
    Collectors.toMap(
        MyObject::getKey, 
        MyObject::getValue,
        (e1, e2) -> {
            System.out.println("Duplicate keys !!!");
            return e1;
        }, 
        LinkedHashMap::new
    )
);
Run Code Online (Sandbox Code Playgroud)

如何用重复键打印消息"重复键"?

java java-8 collectors

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

一种在java stream api中指定Collector初始容量的优雅方法

我试图找到一种在java stream api中设置收集器初始容量的好方法.最简单的例子是:

data.stream()
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

我只想将一个带有list大小的int传递给collector,以便不调整内部数组的大小.第一个意图是这样做:

data.stream()
        .collect(Collectors.toList(data.size()));
Run Code Online (Sandbox Code Playgroud)

但不幸的是,toList没有重载以使用参数.我发现了一个解决方案,但它闻起来:

 data.stream()
        .collect(Collectors.toCollection(() -> new ArrayList<>(data.size())));
Run Code Online (Sandbox Code Playgroud)

有没有办法表达它更简单?

java-8 collectors

6
推荐指数
1
解决办法
1065
查看次数

Java流 - 收集组合器

为什么以下代码:

StringBuilder sb22 = IntStream
     .range(1, 101)
     .filter(x -> x > 50)
     .boxed()
     .parallel()
     .collect(// object that is used in accumulator to do accumulating on
              StringBuilder::new, 
              // use object from above and call append on it with each stream element as argument
              (sb, a) -> sb.append(":" + a),  
              // (executes only when using parallel!)
              (sb1, sb2) -> { 
                     System.out.println(Thread.currentThread().getId() + "  " + "sb1=" + sb1 + " AND " + "sb2=" + sb2); 
                     sb1.append("-"+sb2);
              });
Run Code Online (Sandbox Code Playgroud)

产生这个结果:

------------------:51:52:53-:54:55:56-:57:58:59-:60:61:62-:63:64:65-:66:67:68-:69:70:71-:72:73-:74:75-:76:77:78-:79:80:81-:82:83:84-:85:86:87-:88:89:90-:91:92:93-:94:95:96-:97:98-:99:100
Run Code Online (Sandbox Code Playgroud)

不应该首先将part(------------------ …

java java-stream collectors

6
推荐指数
1
解决办法
254
查看次数

以结构化方式组合多个Java流

我想使用Java的流API在对象列表上进行一些计算:

List<Item>.stream()...

Item类包含许多属性.对于其中一些我需要取集合中所有项目的平均值,对于其他属性我需要做其他形式的计算.我一直在做单独的流/收集器调用来实现这一点,虽然我没有遇到任何性能问题(因为列表大小通常大约为100)我想学习如何更简洁,也就是循环一次.

ItemCalculation itemCalculation = ItemCalculation.builder()
    .amountOfItems(itemList.size())
    .averagePrice(itemList.stream()
            .mapToDouble(item -> item.getPrice())
            .average()
            .getAsDouble())
    .averageInvestmentValue(itemList.stream()
            .mapToDouble(item -> getTotalInvestmentValue(item.getInvestmentValue(), item.getInvestmentValuePackaging()))
            .average()
            .getAsDouble())
    .highestWarrantyLimit(itemList.stream()... etc.
Run Code Online (Sandbox Code Playgroud)

我读到了创建一个自定义收集器,但让我的"计算"类只是一行(stream-> customCollector)然后有一个非常臃肿的收集器类来执行实际逻辑似乎有点奇怪.特别是因为以不同的方式收集不同的属性,我需要许多不同的中间计数和其他变量.有什么想法吗?

java java-stream collectors

6
推荐指数
1
解决办法
147
查看次数

为什么相同的比较器在单元测试中的作用与作为Web应用程序运行时的行为不同?

TL; DR:经过多次试验和错误,似乎问题与Tomcat有关,可能与配置的java版本有关,而不是java语言本身.有关详细信息,请参阅下面的"编辑3".

我一直在使用Java 8流和比较器一段时间,以前从未见过这种类型的行为,所以我要求好奇,看看是否有人能找到我的流有什么问题.

我正在研究"Java-8-ifying"一个遗留项目,用流替换我们过时的收集处理(我被问到为什么我这样做,简短的回答是我们基本上重写了项目,但只有时间预算才能逐步完成.我正在做第一步 - 更新java版本.围绕集合逻辑有很多混乱的代码,所以"Java-8-ifying"正在用于清理很多代码和使事情更容易阅读和维护).目前,我们仍在使用旧的数据类型,因此提到的任何日期都是处理java.util.Date实例而不是新的Java 8类型.

这是ServiceRequest.java中的Comparator(它是一个POJO):

public static final Comparator<ServiceRequest> BY_ACTIVITY_DATE_DESC = Comparator.comparing(
        ServiceRequest::getActivityDate, Comparator.nullsLast(Comparator.reverseOrder()));
Run Code Online (Sandbox Code Playgroud)

单元测试时,此比较器按预期工作.具有较晚activityDate的ServiceRequests在结果列表中排在第一位,具有较早activityDate的ServiceRequests位于列表的下方,而具有null activityDate的ServiceRequests位于底部.作为参考,这里是单元测试的完整副本:

@Test
public void testComparator_BY_ACTIVITY_DATE_DESC() {
    ServiceRequest olderRequest = new ServiceRequest();
    olderRequest.setActivityDate(DateUtil.yesterday());

    ServiceRequest newerRequest = new ServiceRequest();
    newerRequest.setActivityDate(DateUtil.tomorrow());

    ServiceRequest noActivityDateRequest = new ServiceRequest();

    List<ServiceRequest> sortedRequests = Arrays.asList(olderRequest, noActivityDateRequest, newerRequest).stream()
            .sorted(ServiceRequest.BY_ACTIVITY_DATE_DESC)
            .collect(Collectors.toList());

    assertEquals(sortedRequests.get(0), newerRequest);
    assertEquals(sortedRequests.get(1), olderRequest);
    assertEquals(sortedRequests.get(2), noActivityDateRequest);
}
Run Code Online (Sandbox Code Playgroud)

注意:DateUtil是一个遗留实用程序,它为我们的测试目的创建java.util.Date实例.

正如我所料,这项测试总是以绚丽的色彩传递.但是,我有一个控制器,它组装一个开放服务请求列表,并按请求者标识符对它们进行分组,并仅将该用户的最新请求选择到映射中.我试图将此逻辑转换为给定的流:

private Map<Long, ServiceRequestViewBean> ServiceRequestsByUser(List<ServiceRequest> serviceRequests) {
    return serviceRequests.stream()
            .sorted(ServiceRequest.BY_ACTIVITY_DATE_DESC)
            .collect(Collectors.toMap(
                    serviceRequest -> serviceRequest.getRequester().getId(),
                    serviceRequest -> new ServiceRequestViewBean(serviceRequest),
                    (firstServiceRequest, secondServiceRequest) …
Run Code Online (Sandbox Code Playgroud)

java sorting tomcat java-stream collectors

6
推荐指数
1
解决办法
147
查看次数

Java使用"set"进行分组和映射,但如果所有值都为"null",则需要一个空集

在我的Java 11应用程序中,我想从存储库获取产品更新.一个产品更新有一个updateIdproductIds要更新的列表.

  • 如果没有应该更新的产品编号以进行更新updateId = X,我仍然希望写入另一个我已处理更新的表X; updateStatusRepository.setStatusProcessing(updateId)并且updateStatusRepository.setStatusProcessed(updateId)应该仍然需要这个updateId.

  • 如果存在产品更新,则应在中进行处理ProductProcessingService.

现在,groupingBymapping给我一个带有null条目而不是空集的Set,这就是我之后删除所有null产品ID的原因.

List<ProductUpdate> productUpdateList = updateStatusRepository.getProductUpdates();
Map<String, Set<String>> productUpdateMap = productUpdateList
          .stream()
          .collect(
              Collectors.groupingBy(
                  ProductUpdate::getUpdateId,
                  Collectors.mapping(ProductUpdate::getProductNo, Collectors.toSet())));

productUpdateMap.forEach(
          (updateId, productIds) -> {
        try {
          updateStatusRepository.setStatusProcessing(updateId);
          productIds.remove(null);
          if(!productIds.isEmpty()) {
            productProcessingService.performProcessing(Lists.newArrayList(productIds));
          }
          updateStatusRepository.setStatusProcessed(updateId);
        } catch (Exception e) {
              //
        }
});
Run Code Online (Sandbox Code Playgroud)

我更喜欢是否可以以mapping这样的方式使用它,如果所有值都是直接传递空集null.

有没有办法优雅地做到这一点?

java java-stream collectors

6
推荐指数
1
解决办法
181
查看次数

合并Java流

我有很大的按文档ID和版本排序的版本化文档流。

例如,Av1,Av2,Bv1,Cv1,Cv2

我必须将其转换为另一个Stream,其记录通过文档ID进行汇总。

A [v1,v2],B [v1],C [v1,V2]

可以不使用而完成此操作Collectors.groupBy()吗?我不想使用groupBy()它,因为它将在分组之前将流中的所有项目加载到内存中。从理论上讲,不需要将整个流加载到内存中,因为它是有序的。

java java-stream collectors

6
推荐指数
1
解决办法
120
查看次数

标签 统计

collectors ×10

java ×9

java-stream ×7

java-8 ×5

grouping ×1

iterator ×1

lambda ×1

sorting ×1

tomcat ×1