如何在不覆盖等于的情况下查找重复元素
How to find the duplicate elements without override equals
我有一个列表 class A
public class A {
String port;
String ip;
String name;
Obeject ...others;
}
在此列表中,我想找到共享相同 ip 和端口的重复元素。
重写 equals() 来比较 ip 和端口,使用 hashSet 可能是解决这个问题的方法。但我认为 equals() 不应该被覆盖,因为这个 class 中还有其他字段,它可能会混淆逻辑。
使用 TreeSet 和实现 Comparator 是另一种方法。但是 ip 和端口很难比较哪个更大,因为我们有 ipv6、ipv4、ip 范围、端口范围等。在 compare() 中,如果只有 return 0 当 ip 和端口相等且 return 1如果它们不相等将导致逻辑错误。因为TreeSet是由红黑树实现的。
一个名为 AHelper 的子class 覆盖 equals() 可能会起作用。但是我觉得很蠢
请问还有其他方法可以解决这个问题吗? ~~~非常感谢。
我认为选项 2 是最好的选择,因为比较器的工作是某种外部因素,它引入了 ordering.Since 你提到 IP 很难比较,为什么不将 IPv4 和 IPv6 分开 attributes.What 对象中填充的数据类型必须 controlled.Its 就像说我如何比较我的全名和我的昵称 name.I 认为主要问题是 [=17= 没有通用规则] 你比较以及你如何比较是你必须想出的 designer/developer
声明一个新的 class IpAndPort
,它只包含 ip
和 port
字段,并覆盖 class 上的 equals()
所以它比较了两个字段。定义一个 Map
,其键为 IpAndPort
,其值为 A
或 List<A>
,具体取决于您的需要。遍历 List<A>
,并为每个元素创建 IpAndPort
。现在将其添加到 IpAndPort
是键的映射中,并且 (1) 将 A
作为值添加到映射中;或 (2) 为 List<A>
中的每个键收集映射中的所有 A
。或者其他东西(你可以把它变成 Map<IpAndPort, Integer>
并且只计算每个 IP/Port 键的值的数量)。
您还可以通过使 IpAndPort
对象成为 A
中的实例变量来消除一些冗余,替换 ip
和 port
变量。
在java8中可以使用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
将仅保留对象 A
,其 ip
和 port
与 list2
.
相同
我有一个列表 class A
public class A {
String port;
String ip;
String name;
Obeject ...others;
}
在此列表中,我想找到共享相同 ip 和端口的重复元素。
重写 equals() 来比较 ip 和端口,使用 hashSet 可能是解决这个问题的方法。但我认为 equals() 不应该被覆盖,因为这个 class 中还有其他字段,它可能会混淆逻辑。
使用 TreeSet 和实现 Comparator 是另一种方法。但是 ip 和端口很难比较哪个更大,因为我们有 ipv6、ipv4、ip 范围、端口范围等。在 compare() 中,如果只有 return 0 当 ip 和端口相等且 return 1如果它们不相等将导致逻辑错误。因为TreeSet是由红黑树实现的。
一个名为 AHelper 的子class 覆盖 equals() 可能会起作用。但是我觉得很蠢
请问还有其他方法可以解决这个问题吗? ~~~非常感谢。
我认为选项 2 是最好的选择,因为比较器的工作是某种外部因素,它引入了 ordering.Since 你提到 IP 很难比较,为什么不将 IPv4 和 IPv6 分开 attributes.What 对象中填充的数据类型必须 controlled.Its 就像说我如何比较我的全名和我的昵称 name.I 认为主要问题是 [=17= 没有通用规则] 你比较以及你如何比较是你必须想出的 designer/developer
声明一个新的 class IpAndPort
,它只包含 ip
和 port
字段,并覆盖 class 上的 equals()
所以它比较了两个字段。定义一个 Map
,其键为 IpAndPort
,其值为 A
或 List<A>
,具体取决于您的需要。遍历 List<A>
,并为每个元素创建 IpAndPort
。现在将其添加到 IpAndPort
是键的映射中,并且 (1) 将 A
作为值添加到映射中;或 (2) 为 List<A>
中的每个键收集映射中的所有 A
。或者其他东西(你可以把它变成 Map<IpAndPort, Integer>
并且只计算每个 IP/Port 键的值的数量)。
您还可以通过使 IpAndPort
对象成为 A
中的实例变量来消除一些冗余,替换 ip
和 port
变量。
在java8中可以使用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
将仅保留对象 A
,其 ip
和 port
与 list2
.