我有以下课程(有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)
这不可能是对的.我错过了什么?谢谢!
我正在编写一个方法,它接受在这里定义a Map的形式的输入.Map<Term, List<Integer>>Term
方法:
Map并使用Term属性过滤它们.min(List.size(), 5))并将输出添加到全局变量(例如totalSum)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 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)
有任何想法吗?
我有这个代码来获取地图:
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 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)
有没有办法表达它更简单?
为什么以下代码:
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的流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)然后有一个非常臃肿的收集器类来执行实际逻辑似乎有点奇怪.特别是因为以不同的方式收集不同的属性,我需要许多不同的中间计数和其他变量.有什么想法吗?
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 11应用程序中,我想从存储库获取产品更新.一个产品更新有一个updateId和productIds要更新的列表.
如果没有应该更新的产品编号以进行更新updateId = X,我仍然希望写入另一个我已处理更新的表X; updateStatusRepository.setStatusProcessing(updateId)并且updateStatusRepository.setStatusProcessed(updateId)应该仍然需要这个updateId.
如果存在产品更新,则应在中进行处理ProductProcessingService.
现在,groupingBy并mapping给我一个带有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.
有没有办法优雅地做到这一点?
我有很大的按文档ID和版本排序的版本化文档流。
例如,Av1,Av2,Bv1,Cv1,Cv2
我必须将其转换为另一个Stream,其记录通过文档ID进行汇总。
A [v1,v2],B [v1],C [v1,V2]
可以不使用而完成此操作Collectors.groupBy()吗?我不想使用groupBy()它,因为它将在分组之前将流中的所有项目加载到内存中。从理论上讲,不需要将整个流加载到内存中,因为它是有序的。
collectors ×10
java ×9
java-stream ×7
java-8 ×5
grouping ×1
iterator ×1
lambda ×1
sorting ×1
tomcat ×1