合并Java 8中的两个对象列表 [英] Merging two List of objects in java 8

查看:283
本文介绍了合并Java 8中的两个对象列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Java类 Parent ,包含20个属性(attrib1,attrib2 .. attrib20)及其相应的getter和二传手。我还有两个 Parent 对象列表: list1 list2

I have a Java class Parent with 20 attributes (attrib1, attrib2 .. attrib20) and its corresponding getters and setters. Also I have two lists of Parent objects: list1 and list2.

现在我想合并两个列表并避免基于 attrib1 attrib2 。

Now I want to merge both lists and avoid duplicate objects based on attrib1 and attrib2.

使用Java 8:

List<Parent> result = Stream.concat(list1.stream(), list2.stream())
                .distinct()
                .collect(Collectors.toList());   

但在哪个地方我必须指定属性?我应该覆盖 hashCode 等于方法吗?

But in which place I have to specify the attributes? Should I override hashCode and equals method?

推荐答案

如果你想实现等于 hashCode ,那么这个地方就是里面。在该类中添加方法,如

If you want to implement equals and hashCode, the place to do it is inside the class Parent. Within that class add the methods like

    @Override
    public int hashCode() {
        return Objects.hash(getAttrib1(), getAttrib2(), getAttrib3(),
            // …
                            getAttrib19(), getAttrib20());
    }

    @Override
    public boolean equals(Object obj) {
        if(this==obj) return true;
        if(!(obj instanceof Parent)) return false;
        Parent p=(Parent) obj;
        return Objects.equals(getAttrib1(), p.getAttrib1())
            && Objects.equals(getAttrib2(), p.getAttrib2())
            && Objects.equals(getAttrib3(), p.getAttrib3())
            // …
            && Objects.equals(getAttrib19(), p.getAttrib19())
            && Objects.equals(getAttrib20(), p.getAttrib20());
    }

如果你这样做, distinct()流< Parent> 上调用code>将自动做正确的事。

If you did this, distinct() invoked on a Stream<Parent> will automatically do the right thing.

如果您不想(或不能)更改类 Parent ,则没有委托机制可以实现相等,但您可以采用订购,因为它具有委托机制:

If you don’t want (or can’t) change the class Parent, there is no delegation mechanism for equality, but you may resort to ordering as that has a delegation mechanism:

Comparator<Parent> c=Comparator.comparing(Parent::getAttrib1)
        .thenComparing(Parent::getAttrib2)
        .thenComparing(Parent::getAttrib3)
        // …
        .thenComparing(Parent::getAttrib19)
        .thenComparing(Parent::getAttrib20);

这定义了基于属性的订单。它要求属性本身的类型具有可比性。如果你有这样的定义,你可以使用它来实现 distinct()的等价物,基于比较器

This defines an order based on the properties. It requires that the types of the attributes itself are comparable. If you have such a definition, you can use it to implement the equivalent of a distinct(), based on that Comparator:

List<Parent> result = Stream.concat(list1.stream(), list2.stream())
        .filter(new TreeSet<>(c)::add)
        .collect(Collectors.toList());

如果您想将其与并行流一起使用,还有一个线程安全的变体:

There is also a thread-safe variant, in case you want to use it with parallel streams:

List<Parent> result = Stream.concat(list1.stream(), list2.stream())
        .filter(new ConcurrentSkipListSet<>(c)::add)
        .collect(Collectors.toList());

这篇关于合并Java 8中的两个对象列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆