Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8按每个id的最高值筛选列表_Java_Lambda_Java 8_Java Stream - Fatal编程技术网

Java 8按每个id的最高值筛选列表

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

有没有一种方法可以使用Java8特性和lambdas执行以下操作

我有这门课

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;
    }

}