如何在没有覆盖等于的情况下找到重复的元素

时间:2017-07-11 03:45:47

标签: java duplicates set treeset

我有一个A类清单

public class A {
    String port;
    String ip;
    String name;
    Obeject ...others;
}

在此列表中,我想找到共享相同ip和端口的重复元素。

  1. 重写equals()以比较ip和port并使用hashSet可能是一种解决此问题的方法。但我认为equals()不应该被覆盖,因为这个类中还有其他字段,它可能会混淆逻辑。

  2. 使用TreeSet并实现Comparator是另一种方式。但是由于我们有ipv6,ipv4,ip范围,端口范围等,所以ip和端口很难比较,因为我们有ipv6,ipv4,ip范围,端口范围等。在compare()中,如果只在ip和端口相等时返回0并且如果它们不相等则返回1将导致逻辑错误。因为TreeSet是由红黑树实现的。

  3. 一个名为AHelper的子类可以使用覆盖的equals()。但我觉得这很愚蠢。

  4. 还有其他方法可以解决这个问题吗? ~~~非常感谢。

3 个答案:

答案 0 :(得分:0)

我认为选项2是最好的选择,因为比较器的工作是引入排序的外部因素。因为你提到IP很难配合,为什么不将IPv4和IPv6作为单独的属性。什么样的数据得到填充在对象中必须进行控制。就像说我如何将我的全名与我的昵称进行比较。我认为主要的问题是没有普遍的比较规则。你比较什么以及你如何比较你将拥有的东西想出一个设计师/开发者

答案 1 :(得分:0)

声明一个仅包含IpAndPortip字段的新类port,并覆盖该类的equals(),以便比较这两个字段。定义一个Map,其密钥为IpAndPort,其值为AList<A>,具体取决于您的需求。浏览List<A>,并为每个元素创建IpAndPort。现在将其添加到IpAndPort是关键字的地图中,并且(1)将A作为值添加到地图中;或者(2)收集地图中A中每个键的所有List<A>。或其他东西(您可以将其设为Map<IpAndPort, Integer>并只计算每个IP /端口密钥的值数。)

您还可以通过在IpAndPort中将A对象变为实例变量来替换ipport变量,从而消除一点冗余。

答案 2 :(得分:0)

在java 8中,您可以使用Predicate过滤List中的元素:

ArrayList<A> list1 = new ArrayList<>();
        ArrayList<A> list2 = new ArrayList<>();

        Stream<A> stream = list1.stream();
        for (A a2 : list2) {
            stream.filter(a1 -> a1.getIp().equals(a2.getIp()) && a1.getPort().equals(a2.getPort()));
        }

list1将仅保留Aipport中相同的对象list2