需要帮助了解Java中比较器接口的内部工作原理

时间:2015-04-21 04:19:57

标签: java

我试图理解Java中Comparator接口背后的理论。特别是,我需要帮助理解compare()方法的返回值如何确定列表顶部的内容。

Java代码

import java.util.Comparator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/*
LOWER VALS. ARE AT TOP OF LIST
*/
class IncreasedComparison implements Comparator<Integer>{

  @Override
  public int compare(Integer first, Integer second) {
   int value = first - second;
   return value;
  } 
}

/*
HIGHER VALS. ARE AT TOP OF LIST
*/
class DecreasedComparison implements Comparator<Integer>{
  @Override
  public int compare(Integer first, Integer second){
    int value = second - first;
    return value;
  }
}


public class ComparisonExample {

public static void main(String[] args) {

    TreeMap<Integer,String> testOne = new TreeMap<>(new IncreasedComparison());
    TreeMap<Integer,String> testTwo = new TreeMap<>(new DecreasedComparison());

    testOne.put(1, "First Entry");
    testOne.put(2, "Second Entry");
    testOne.put(3, "Third Entry");
    testOne.put(4, "Fourth Entry");
    testOne.put(5, "Fifth Entry");

    testTwo.put(1, "First Entry");
    testTwo.put(2, "Second Entry");
    testTwo.put(3, "Third Entry");
    testTwo.put(4, "Fourth Entry");
    testTwo.put(5, "Fifth Entry");

    Set<Map.Entry<Integer,String>> firstOutput = testOne.entrySet();
    Set<Map.Entry<Integer,String>> secondOutput = testTwo.entrySet();

    for(Map.Entry<Integer,String> first : firstOutput){
        System.out.println(first.getKey() + " " + first.getValue());
    }

    System.out.println("\n\n");

    for(Map.Entry<Integer,String> second : secondOutput){
        System.out.println(second.getKey() + " " + second.getValue());
    }

  }

}

输出

1 First Entry
2 Second Entry
3 Third Entry
4 Fourth Entry
5 Fifth Entry



5 Fifth Entry
4 Fourth Entry
3 Third Entry
2 Second Entry
1 First Entry

讨论

查看IncreasedComparison类,当compare方法返回负值时,意味着较低的Keys(和各个元素)位于列表的顶部。然后查看DecreasedComparison类,当compare方法返回正值时,较高的Keys(和相应的元素)位于列表的顶部。

为什么会这样?它出现在哪里,Key值的差异可以决定TreeList元素在一种情况下是否在列表的顶部,但是它可以在下一个的底部?

当实现Comparator接口的对象传递给TreeMap构造函数时,是否会发生这种情况?通过将它放入构造函数中,它是否在TreeMap中设置了先例,compare()方法的负返回值意味着较小的Integer值应位于列表的顶部,反之亦然。 compare()方法?

3 个答案:

答案 0 :(得分:4)

Comparator(a&lt; =&gt; b)的工作方式如下,

-1 a comes before b, generally called less than
 0 a equals b
 1 a comes after b, generally called greater than

Javadoc说(部分)

  

比较其订单的两个参数。当第一个参数小于,等于或大于第二个参数时,返回负整数,零或正整数。

而且,是的。 TreeMap(Comparator)构造函数Javadoc说

  

构造一个新的空树图,根据给定的比较器排序。插入到地图中的所有键必须通过给定的比较器

相互比较

答案 1 :(得分:1)

结果意味着什么

考虑java.util.Comparator.compareTo结果的一种方法如下。让

a ? b

?可以是=><。然后让我们在等式

中加零
a ? b + 0

然后一些代数将?移动到另一个位置

a - b ? 0

如果我们尝试根据?a的值为b添加不同的可能值,我们会有以下三种组合

if (a > b) then (a - b > 0)
if (a < b) then (a - b < 0)
if (a = b) then (a - b == 0)

您可以获得正,负和零值整数结果。

为什么要查看这些结果?

对于整数,compareTo逻辑将有点愚蠢,因为您可以轻松地说a > b,但对于其他非简单类型,例如String,这更有意义。

想象一个没有compareTo方法的世界。这意味着我们必须实现至少两种方法进行比较:isGreaterThanequals方法。只有那两个就足够了,因为它不会是

!isGreaterThan(x) && !equals(x)

然而,如果compareTo从长远来看会节省更多的电话,那么所有这些都会涉及更多的方法调用。

答案 2 :(得分:0)

首先,比较者有一个合同:当他们收到两个值ab时,他们会通过返回一个负值表示a来到b之前,ba之前返回一个正数,并且通过返回零来认为它们应该被认为是相等的等级。

TreeMap特别存储其比较器以供将来参考,并在每次访问TreeMap中的内容时多次询问它。要准确了解发生了什么以及何时发生,请考虑在System.out.println(first, second)函数的顶部添加compare