Создание набора объектов из сгенерированного класса 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
в качестве сообщения буфера протокола и использование полученного в результате сгенерированного Javaclass.
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