一组java Protobuf对象与Class对象的行为有所不同

时间:2018-06-01 14:59:01

标签: java set protocol-buffers

从生成的protobuf类中创建一组具有相同值的对象,用于标识和删除集合中的重复项(这是因为匹配hashCode()?)。但是,使用具有相同成员的类和具有相同数据的对象创建Set不会从集中删除重复项,因为它会为创建的对象分配新地址。 protobuf如何维护它创建的对象的地址,并在创建具有相同值的新对象时提供相同的对象?有人可以解释为什么Set<>构造存在这种差异吗?

考虑以下名为NodeJava的类,该类是在成员hostport的网络中定义节点的类。

public class NodeJava {
    private String host;
    private Integer port;

    public NodeJava(String host, Integer port) {
        this.host = host;
        this.port = port;
    }
}

现在让我们创建HashSetNodeJava个对象,如下所示:

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

1 个答案:

答案 0 :(得分:0)

设置使用equals(和扩展名hashCode)来确定两个对象是否“相同”。在NodeJava类中,您没有实现equals,因此只有当两个对象是同一个对象时才会相等(即a==b}。

如果您查看生成的NodeProto代码,您可能会找到equals的实现(以及hashCode的相应实现),其中包含将字段考虑在内,因此即使您create的第二个和第三个实例是单独的对象,它们也被认为是相等的。