pme*_*esm 2 java arrays grouping list java-stream
想象一个具有 3 个属性的简单对象:
public class Obj {
boolean toBeAdded;
String type;
int order;
public Obj(boolean toBeAdded, String type, int order) {
this.toBeAdded = toBeAdded;
this.type = type;
this.order = order;
}
public boolean isToBeAdded() {
return toBeAdded;
}
public String getType() {
return type;
}
public int getOrder() {
return order;
}
}
Run Code Online (Sandbox Code Playgroud)
想象一下,我有一个包含多个Obj不同类型的列表:
import java.util.Arrays;
import java.util.List;
public class Utils {
static List<Obj> createA(){
List<Obj> list = Arrays.asList(
new Obj(true, "A", 1),
new Obj(false, "A", 2),
new Obj(true, "A", 3),
new Obj(false, "A", 4)
);
return list;
}
static List<Obj> createB(){
List<Obj> list = Arrays.asList(
new Obj(true, "B", 1),
new Obj(false, "B", 2),
new Obj(true, "B", 3),
new Obj(false, "B", 4)
);
return list;
}
static List<Obj> createC(){
List<Obj> list = Arrays.asList(
new Obj(false, "C", 1),
new Obj(false, "C", 2),
new Obj(true, "C", 3),
new Obj(true, "C", 4)
);
return list;
}
}
Run Code Online (Sandbox Code Playgroud)
我想以某种方式过滤此列表,并为每个可以添加的列表Obj( order) 提供最新的(最高值)。typetoBeAdded = true
对于这个例子,结果应该是一个列表:
我知道如何过滤和排序,但我仍然无法理解如何在每个子类型中获得第一个。这是违反Stream规则的吗?由于我想做的基本上是解析N个不同的子流,对于N个不同的types?
这是我到目前为止可以做的:
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class MainTest {
public static void main(String[] args) {
List<Obj> list = new ArrayList<>();
list.addAll(Utils.createA());
list.addAll(Utils.createB());
list.addAll(Utils.createC());
System.out.println(list);
List<Obj> filteredList = list
.stream()
.filter(Obj::isToBeAdded)
.sorted(Comparator.comparingInt(Obj::getOrder).reversed())
.collect(Collectors.toList());
System.out.println(filteredList);
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这只是做简单的部分 - 过滤和排序。我仍然需要findFirst()为每个type. 有没有办法做到这一点?
我是否必须执行 3 个不同的流(每种类型一个)然后合并列表?有没有办法在不知道我们将拥有多少类型的情况下做到这一点?我也读过,collect(Collectors.groupingBy())但这会为每种类型创建不同的地图,这是我不想要的。
groupingBy与minBy/的下游一起使用可以在这里提供帮助maxBy。如果过滤后的值存在于每种类型,这将提供一个映射来查找。
Map<String, Optional<Obj>> groupMaxOrderByType = list.stream()
.filter(Obj::isToBeAdded)
.collect(Collectors.groupingBy(Obj::getType,
Collectors.maxBy(Comparator.comparingInt(Obj::getOrder)))); //highest order
Run Code Online (Sandbox Code Playgroud)
对这些对象的查找或访问将转换为以下内容:
Obj maxPerTypeA = groupMaxOrderByType.get("A").orElse.. // similar for each type
Run Code Online (Sandbox Code Playgroud)
编辑:或者,如果您要将所有这些当前类型收集到最终结果中,您可以按照访问Map.
List<Obj> result = groupMaxOrderByType.values().stream()
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
编辑:或者摆脱处理Optional,您可以使用toMapwith BinaryOperator.maxBy作为合并功能。
Map<String, Obj> groupMaxOrderByType = list.stream()
.filter(Obj::isToBeAdded)
.collect(Collectors.toMap(Obj::getType, Function.identity(),
BinaryOperator.maxBy(Comparator.comparingInt(Obj::getOrder))));
List<Obj> result = new ArrayList<>(groupMaxOrderByType.values());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
84 次 |
| 最近记录: |