番石榴ComparisonChain为什么它不会在第一次比较后终止非零结果

时间:2014-07-16 23:43:25

标签: java guava comparisonchain

番石榴中的比较链是否应该懒散地评估比较?在下面的代码中,如果链没有终止,NullComparator(apache)将返回一个非零值?

来自docs: ComparisonChain实现停止调用其输入' compareTo和compare方法,只要其中一个返回非零结果

    String x = null;
    String y = "y";
    ComparisonChain.start().compare(x,y, new NullComparator(false)).
            compare(x.getBytes().toString(), y.getBytes().toString()).result();

注意:上面只是一个例子。也许这将是更好的例子

ComparisonChain.start().compare(x,y, new NullComparator(false)).
        compare(x.getBytes(), y.getBytes(), UnsignedBytes.lexicographicalComparator()).result();

2 个答案:

答案 0 :(得分:5)

没有什么可以阻止Java将参数评估为compare(),即使该方法什么也不做。 x.getBytes()会抛出NPE,因为xnull

也许这会起作用?

return Ordering.onResultOf(new Function<String, String>() {
            @Override
            public String apply(String input) {
                return input.getBytes().toString();
            }
        })
        .nullsFirst()
        .compare(x, y);

请注意input.getBytes().toString()排序方式可能不太合适(看起来像[B@35c41b)。

答案 1 :(得分:3)

那是因为什么是懒惰是对比较的调用,而不是对x.getBytes()的调用,因此是NPE! 即:

ComparisonChain.start()
  .compare(x,y, new NullComparator(false))
  .compare(x.getBytes().toString(), y.getBytes().toString()) // <-- tries to invoke compare with two objects
  .result();

您应该尝试使用比较器,如下所示:

ComparisonChain.start()
  .compare(x,y, new NullComparator(false))
  .compare(x, y, new Comparator<String>() {
    int compare(String a, String b) {
      return a.getBytes().toString().compareTo(b.getBytes().toString());
    }
  })
  .result();

或者使用Java 8:

ComparisonChain.start()
  .compare(x,y, new NullComparator(false))
  .compare(x, y, (a, b) -> a.getBytes().toString().compareTo(b.getBytes().toString()))
  .result();

请注意,在实际情况中比较getBytes().toString()可能不是一个好主意......