从生成的protobuf类中创建一组具有相同值的对象,用于标识和删除集合中的重复项(这是因为匹配hashCode()
?)。但是,使用具有相同成员的类和具有相同数据的对象创建Set
不会从集中删除重复项,因为它会为创建的对象分配新地址。 protobuf
如何维护它创建的对象的地址,并在创建具有相同值的新对象时提供相同的对象?有人可以解释为什么Set<>
构造存在这种差异吗?
考虑以下名为NodeJava
的类,该类是在成员host
,port
的网络中定义节点的类。
public class NodeJava {
private String host;
private Integer port;
public NodeJava(String host, Integer port) {
this.host = host;
this.port = port;
}
}
现在让我们创建HashSet
个NodeJava
个对象,如下所示:
Set<NodeJava> nodes = new HashSet<>();
nodes.add(new NodeJava("localhost", 12345)); // New address to each of the objects
nodes.add(new NodeJava("localhost", 12346));
nodes.add(new NodeJava("localhost", 12346));
System.out.println(nodes.size()); // 3 is the result
同样,将NodeJava
定义为协议缓冲区消息并使用生成的java生成的类。
message NodeProto {
string host = 1;
uint32 port = 2;
}
我们可以使用构建器模式构建对象,如下所示:
private NodeProto create(String host, Integer port) {
NodeProto.Builder node = NodeProto.newBuilder();
node.setHost(host);
node.setPort(port);
return node.build();
}
同样,创建一组这些对象会产生不同的结果:
Set<NodeProto> nodes = new HashSet<>();
nodes.add(create("localhost", 12345));
nodes.add(create("localhost", 12346));
nodes.add(create("localhost", 12346)); // Same address as older
System.out.println(nodes.size()); // 2 is the result
答案 0 :(得分:0)
设置使用equals
(和扩展名hashCode
)来确定两个对象是否“相同”。在NodeJava
类中,您没有实现equals
,因此只有当两个对象是同一个对象时才会相等(即a==b
}。
如果您查看生成的NodeProto
代码,您可能会找到equals
的实现(以及hashCode
的相应实现),其中包含将字段考虑在内,因此即使您create
的第二个和第三个实例是单独的对象,它们也被认为是相等的。