Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top