Набор объектов Java Protobuf и объектов класса ведут себя по-разному - PullRequest
0 голосов
/ 01 июня 2018

Создание набора объектов из сгенерированного класса 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

1 Ответ

0 голосов
/ 01 июня 2018

Наборы используют equals (и с расширением hashCode), чтобы определить, являются ли два объекта "одинаковыми".В вашем классе NodeJava вы не реализуете equals, поэтому два объекта равны, только если они являются одним и тем же объектом (т. Е. Если a==b).

Если вы посмотрите на код для NodeProto, которое генерируется, вероятно, вы найдете реализацию equals (и соответствующую реализацию hashCode), которая учитывает значения полей, так что даже во втором и третьем экземплярах вы create являются отдельными объектами, они считаются равными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...