Java 8按每个id的最高值筛选列表
有没有一种方法可以使用Java8特性和lambdas执行以下操作 我有这门课Java 8按每个id的最高值筛选列表,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,有没有一种方法可以使用Java8特性和lambdas执行以下操作 我有这门课 public class A{ private String id; private int version; // getters... } 输入(列表按id和版本升序排列): 我想列出每个id的最高版本,因此结果应该如下所示: [{"1",2},{"2",2}] 我已经有了一个解决方案,但我不太喜欢它。我想也许有更好的方式使用Java8 static List<A> remo
public class A{
private String id;
private int version;
// getters...
}
输入(列表按id和版本升序排列):
我想列出每个id的最高版本,因此结果应该如下所示:
[{"1",2},{"2",2}]
我已经有了一个解决方案,但我不太喜欢它。我想也许有更好的方式使用Java8
static List<A> removeOldVersions(List<A> aList) {
Map<String, A> map = new HashMap<>();
aList.forEach(a -> map.put(a.getId(), a));
return (List<A>) map.values();
}
静态列表移除旧版本(列表列表){
Map Map=newhashmap();
aList.forEach(a->map.put(a.getId(),a));
返回(列表)map.values();
}
将每一对添加到映射中,在覆盖之前检查它是否已经存在并且具有较低的值
经典方法:
{
List<A> in = Arrays.asList(new A("'1'", 1),
new A("'1'", 2),
new A("'2'", 1),
new A("'2'", 2));
Map<String, Integer> map = new LinkedHashMap<>(in.size()); // 'Linked' just keeps the original ordering
for (A element : in) {
@Nullable Integer version = map.get(element.id);
if (version == null || version < element.version)
map.put(element.id, element.version);
}
System.out.println(map);
}
{
List in=Arrays.asList(新的A('1',1),
新的A(“'1'”,2),
新的A(“'2',1),
新的A('2',2));
Map Map=newlinkedhashmap(in.size());/“Linked”只保留原始顺序
对于(元素:in){
@可为空的整数版本=map.get(element.id);
if(version==null | | version
输出:
{'1'=2,'2'=2}
好的,您可以收集到一个Map
并通过BinaryOperator.maxBy
合并条目。计算完成后,对其调用值
(将返回集合
):
介绍
有两种方法可以实现这一点,它们都使用比较器
,我建议您在以下链接中阅读更多关于它们的内容:
我想向您展示我最简单的方法,而无需编写自己的过滤器/独特的alghorytm。此解决方案将使用Java8的流API
(假设您在两个示例中都使用了ArrayList
或HashSet
)
使用流
公共类分拣机{
私人期末甲级{
私有字符串id;
私有int版本;
专用A(字符串id,int版本){
this.id=id;
this.version=版本;
}
公共字符串getId(){
返回id;
}
public int getVersion(){
返回版本;
}
}
公共无效排序(){
最终ArrayList=新ArrayList(){{
增加(新的A(“1”,1));
增加(新的A(“1”,2));
增加(新的A(“2”,1));
添加(新的A(“2”,2));
}};
//使用列表,因为我们希望确保我们的列表是有序的
list.stream().sorted(Comparator.comparingit(o->o.version)).filter(distinctByKey(a->a.id)).collect(Collectors.toList());
}
私有静态谓词distinctByKey(功能那么,您的代码中有哪些不起作用?请注意,当您包括您的尝试时,这些问题会带来更积极的反馈。您知道,存在许多与您的要求非常相似的问题。您是否尝试过自己研究此主题。我曾试图通过分组方式
找到解决方案,但迄今为止最接近的是我设法制作的是一张地图
+1@Eran我假设是groupingBy(…,Collectors.maxBy…
;)
{
List<A> in = Arrays.asList(new A("'1'", 1),
new A("'1'", 2),
new A("'2'", 1),
new A("'2'", 2));
Map<String, Integer> map = new LinkedHashMap<>(in.size()); // 'Linked' just keeps the original ordering
for (A element : in) {
@Nullable Integer version = map.get(element.id);
if (version == null || version < element.version)
map.put(element.id, element.version);
}
System.out.println(map);
}
yourList.stream()
.collect(Collectors.toMap(
A::getId,
Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(A::getVersion))))
.values()
public class Sorter {
private final class A {
private String id;
private int version;
private A(String id, int version) {
this.id = id;
this.version = version;
}
public String getId() {
return id;
}
public int getVersion() {
return version;
}
}
public void sort() {
final ArrayList<A> list = new ArrayList<A>() {{
add(new A("1", 1));
add(new A("1", 2));
add(new A("2", 1));
add(new A("2", 2));
}};
//Using List as we want to be sure that our List is in order
list.stream().sorted(Comparator.comparingInt(o -> o.version)).filter(distinctByKey(a -> a.id)).collect(Collectors.toList());
}
private static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor)
{
Map<Object, Boolean> map = new ConcurrentHashMap<>();
return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
}