I have class implementing Comparator<String> which should sort strings in such manner that strings with first word being roman number should be before string that don't begin with roman number, and if both strings begin with roman literal, there should be two cases:

  1. sort by roman number and then if equal by rest of string
  2. sort by rest of string and if equal than roman number

I wanted to use Guava's ComparisonChain but encountered two problems:

  1. During debug in Eclipse I can't see what's inside ComparisonChain object (even while being in ComparisonChain class).
  2. comparisonChain.result() in second example above always returns 0 (I can't inspect flow because of problem #1) for values like "XI Something", "III Something" etc. (conversion to long is OK - I checked values).

What is the problem here? I can use comparisonChain object like above (by making variable and adding .compares in some ifs like with builders), can't I?

This code:

  if (romanComparisionFirst) {
    return ComparisonChain.start()
        .compare(Roman.toLong(leftFirstWord), Roman.toLong(rightFirstWord))
        .compare(WORDS_JOINER.join(leftWordsTail), WORDS_JOINER.join(rightWordsTail), collator)
        .result();
  } else {
    return ComparisonChain.start()
        .compare(WORDS_JOINER.join(leftWordsTail), WORDS_JOINER.join(rightWordsTail), collator)
        .compare(Roman.toLong(leftFirstWord), Roman.toLong(rightFirstWord))
        .result();
  }

and this:

  final ComparisonChain comparisionChain = ComparisonChain.start();
  if (romanComparisionFirst) {
    comparisionChain
        .compare(Roman.toLong(leftFirstWord), Roman.toLong(rightFirstWord))
        .compare(WORDS_JOINER.join(leftWordsTail), WORDS_JOINER.join(rightWordsTail), collator);
  } else {
    comparisionChain
        .compare(WORDS_JOINER.join(leftWordsTail), WORDS_JOINER.join(rightWordsTail), collator)
        .compare(Roman.toLong(leftFirstWord), Roman.toLong(rightFirstWord));
  }
  return comparisionChain.result();

give different results - first case is OK, second always 0. So question is: Can I use ComparisonChain like shown if second case or is this behavior a bug?

有帮助吗?

解决方案

Each compare method of the ComparisonChain returns a ComparisonChain, which is not necessarily the chain on which compare is invoked. The first snippet doesn't ignore the result (and is thus correct), but the second one ignores the result, and is thus incorrect.

It would be correct if it did:

comparisionChain = comparisionChain.compare(...).compare(...);

See http://docs.guava-libraries.googlecode.com/git-history/v10.0.1/javadoc/src-html/com/google/common/collect/ComparisonChain.html#line.89 for the source code.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top