我有一系列未分类的项目和一组比较器.我想通过使用"thenComparing"(Multisort)将所有比较器应用到流中.是否有比以下代码更优雅的方式来实现这一点?
Stream unsorted = ...;
Stream<Comparator> comparators = ...;
Comparator compareFunc = comparators.reduce(null, (a, b) -> {
if(a == null) {
return b;
}else {
return a.thenComparing(b);
}
});
Stream result = unsorted.sorted(compareFunc);
Run Code Online (Sandbox Code Playgroud) 我正在创建一个扑克排名求解器,我必须在一组牌中计算具有相同套装或同等级别的牌.HashMap如果集合中有多个排名,我在这里创建并增加值.
private boolean isFourOfAKind() {
Map<RANK, Integer> rankDuplicates = new HashMap<>();
for(Card card : cards) {
rankDuplicates.put(card.getRank(), rankDuplicates.getOrDefault(card.getRank(), 0) + 1);
}
return rankDuplicates.containsValue(4);
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否有可能使用流与java流完全相同的事情.它看起来像这样:
private boolean isFourOfAKind() {
Map<RANK, Integer> rankDuplicates = cards.stream()
.map(Card::getRank)
.collect(Collectors.toMap(/*...something goes here..*/)); // of course this is very wrong, but you can see what I'm aiming at.
return rankDuplicates.containsValue(4);
}
Run Code Online (Sandbox Code Playgroud) 我正在从丑陋的嵌套for循环转换为java中漂亮的设计lambda表达式.
这是我的实际代码
for (String foo : foos) {
for (Bar bar : bars) {
if (bar.getFoo().equals(foo)) {
FooBar fooBar = new FooBar();
fooBar.setBar(bar);
listOfFooBar.add(fooBar);
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的实际lambda代码替换上面的代码
foos.forEach(i -> bars.stream().filter(p -> p.getFoo().equals(i)).findFirst().ifPresent(p -> {
FooBar s = new FooBar();
fooBar.setBar(bar);
listOfFooBar.add(fooBar);
}));
Run Code Online (Sandbox Code Playgroud)
我的问题是,有一种方法可以填充listOfFooBar某种collect()方法吗?
就像是 listOfFooBar = foos.forEach(.....).collect(Collectors.toList());
一个事实是,条形图总是包含每个foo,foos基本上是条形图的一小部分.
如果有更好的方法(在性能或优雅方面)做那个lambda,请分享.
我有一个A类似的列表
class A {
private Integer keyA;
private Integer keyB;
private String text;
}
Run Code Online (Sandbox Code Playgroud)
我想转移aList到嵌套Map映射由keyA和keyB
所以我创建下面的代码.
Map<Integer, Map<Integer,List<A>>> aMappedByKeyAAndKeyB = aList.stream()
.collect(Collectors.collectingAndThen(Collectors.groupingBy(A::getKeyA), result -> {
Map<Integer, Map<Integer, List<A>>> nestedMap = new HashMap<Integer, Map<Integer, List<A>>>();
result.entrySet().stream().forEach(e -> {nestedMap.put(e.getKey(), e.getValue().stream().collect(Collectors.groupingBy(A::getKeyB)));});
return nestedMap;}));
Run Code Online (Sandbox Code Playgroud)
但我不喜欢这段代码.
我想如果我使用flatMap,我可以更好地编码.
但我不知道如何使用flatMap这种行为.
我的情况是:
class Person {
String id ;
String name;
String age;
}
List<Person> list1 = {p1,p2, p3};
List<Person> list2 = {p4,p5, p6};
Run Code Online (Sandbox Code Playgroud)
我想知道是否有人list1有相同的名字和年龄,list2但不介意id.
什么是最好和最快的方式?
我想知道是否有任何漂亮的方式使用新的Stream API来"分组"值序列.
例如,将一系列整数拆分为整数组,其中每个组都是一个递增的数字序列:
IntStream seq = IntStream.of(1, 2, 3, -1, -1, 1, 2, 1, 2);
IntFunction next = i -> i + 1;
// DESIRED OUTPUT: [[1,2,3], [-1], [-1], [1,2], [1,2]]
Run Code Online (Sandbox Code Playgroud) 我有一个类定义的类
public class TimePeriodCalc {
private double occupancy;
private double efficiency;
private String atDate;
}
Run Code Online (Sandbox Code Playgroud)
我想使用Java 8 Stream API执行以下SQL语句.
SELECT atDate, AVG(occupancy), AVG(efficiency)
FROM TimePeriodCalc
GROUP BY atDate
Run Code Online (Sandbox Code Playgroud)
我试过了 :
Collection<TimePeriodCalc> collector = result.stream().collect(groupingBy(p -> p.getAtDate(), ....
Run Code Online (Sandbox Code Playgroud)
可以在代码中添加什么来选择多个属性?我正在考虑使用多个收集器,但实际上不知道如何操作.
我有以下代码:
interface Device {
// ...
boolean isDisconnected();
void reconnect();
}
interface Gateway {
// ...
List<Device> getDevices();
}
...
for (Gateway gateway : gateways) {
for(Device device : gateway.getDevices()){
if(device.isDisconnected()){
device.reconnect();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想使用Stream API重构代码.我的第一次尝试如下:
gateways
.stream()
.forEach(
gateway -> {
gateway
.getDevices()
.parallelStream()
.filter(device -> device.isDisconnected())
.forEach(device -> device.reconnect())
;
}
)
;
Run Code Online (Sandbox Code Playgroud)
我不喜欢它,经过一些修改后我最终得到了这段代码:
gateways
.parallelStream()
.map(gateway -> gateway.getDevices().parallelStream())
.map(stream -> stream.filter(device -> device.isDisconnected()))
.forEach(stream -> stream.forEach(device -> device.reconnect()))
;
Run Code Online (Sandbox Code Playgroud)
我的问题是是否有办法避免嵌套forEach.
我正在寻找一种方法来实现非终端分组操作,这样内存开销将是最小的.
例如,考虑distinct().在一般情况下,它别无选择,只能收集所有不同的项目,然后才向前流式传输.但是,如果我们知道输入流已经排序,则可以使用最少的内存"在运行中"完成操作.
我知道我可以使用迭代器包装器并自己实现分组逻辑来实现迭代器.是否有更简单的方法来使用流API来实现它?
- 编辑 -
我发现了一种滥用Stream.flatMap(..)来实现此目的的方法:
private static class DedupSeq implements IntFunction<IntStream> {
private Integer prev;
@Override
public IntStream apply(int value) {
IntStream res = (prev != null && value == prev)? IntStream.empty() : IntStream.of(value);
prev = value;
return res;
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
IntStream.of(1,1,3,3,3,4,4,5).flatMap(new DedupSeq()).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
哪个印刷品:
1
3
4
5
Run Code Online (Sandbox Code Playgroud)
通过一些更改,相同的技术可用于任何类型的存储器有效的流序列分组.无论如何,我不太喜欢这个解决方案,而且我正在寻找更自然的东西(比如映射或过滤工作的方式).此外,我在这里违约,因为提供给flatMap(..)的函数是有状态的.
我有一个问题,用Java 8分组两个值.
我的主要问题是关于分组两个字段,我正确地组合了一个字段,getNameOfCountryOrRegion()但现在我对groupingBy另一个被调用的字段感兴趣leagueDTO.
Map<String, List<FullCalendarDTO>> result = countryDTOList.stream()
.collect(Collectors.groupingBy(
FullCalendarDTO::getNameOfCountryOrRegion));
Run Code Online (Sandbox Code Playgroud)
以下课程:
public class FullCalendarDTO {
private long id;
private TeamDTO localTeam;
private TeamDTO visitorTeam;
private LocationDTO location;
private String leagueDTO;
private String timeStamp;
private String nameOfCountryOrRegion;
}
Run Code Online (Sandbox Code Playgroud)
结果将通过分组nameOfCountryOrRegion和leagueDTO.
java ×10
java-8 ×10
java-stream ×10
collections ×2
lambda ×2
collectors ×1
foreach ×1
grouping ×1
hashmap ×1
sorting ×1