Google guava ImmutableList equals方法返回的结果与java.utils.List不同,打破了List-Interface契约?

时间:2016-03-27 01:33:45

标签: java guava

我偶然发现了问题,而且我不确定我是否遗漏了某些东西,或者有什么东西被打破了。

我使用谷歌番石榴(19.0)。当我测试ImmutableLists是否平等时,发生了一些可疑的事情。

在Javadoc到ImmutableList中,它表示ImmutableList实现了java.util.List接口 http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableList.html

因此,我认为ImmutableList的equals方法将遵循由java.util.List给出的契约,并为相同的列表返回相同的结果

在List.equals()中说 " [...]换句话说,如果两个列表包含相同顺序的相同元素,则它们被定义为相等。此定义确保equals方法在List接口的不同实现中正常工作。"

https://docs.oracle.com/javase/6/docs/api/java/util/List.html#equals(java.lang.Object)

现在想想这个小代码示例

    ImmutableList.Builder<String> builder1 = new ImmutableList.Builder<>();
    builder1.add("Test1");
    List<String> list1 = builder1.build();


    ImmutableList.Builder<String> builder2 = new ImmutableList.Builder<>();
    builder1.add("Test1");
    List<String> list2 = builder2.build();

    System.out.println(list1.equals(list2));
    //--> false


    List<String> defaultList1 = new LinkedList<>();
    defaultList1.add("Test1");

    List<String> defaultList2 = new LinkedList<>();
    defaultList2.add("Test1");

    System.out.println(defaultList1.equals(defaultList2));
    // --> true

现在,您期望得到什么输出?

我预计两个测试都是 true 。 但实际产量不同。正如预期的那样,java版本的equals返回true。但番石榴版本返回false。

如果你现在看一下google immutableList的javadoc,它会说equals方法返回o1 == o2(这违反了List-Interface契约)。所以我理解为什么我的代码示例以它的工作方式工作。

我认为这不是&#34;错误&#34;谷歌家伙,但我对Iterfaces和合同的理解存在问题

1 个答案:

答案 0 :(得分:2)

您要将元素添加到同一个构建器(在您的案例builder1中)。见下文。所以builder2实际上没有任何东西,而且等于返回false。

ImmutableList.Builder<String> builder1 = new ImmutableList.Builder<>();
builder1.add("Test1"); // builder1
List<String> list1 = builder1.build();


ImmutableList.Builder<String> builder2 = new ImmutableList.Builder<>();
builder1.add("Test1"); // again builder1
List<String> list2 = builder2.build();

System.out.println(list1.equals(list2));
//--> false


List<String> defaultList1 = new LinkedList<>();
defaultList1.add("Test1");

List<String> defaultList2 = new LinkedList<>();
defaultList2.add("Test1");

System.out.println(defaultList1.equals(defaultList2));
// --> true