使用Comparator和Java中的对象列表

时间:2018-05-02 20:30:24

标签: java generics java-8 comparator

我想通过键(String类型)对Type AVLNode的对象进行排序。我实例化了一个Comparator,并希望在String属性上应用compareTo方法。但是,我的IDE向我显示错误Cannot resolve method compareTo。我不明白为什么我不能在字符串上使用compareTo方法。

import java.util.*;

public class AVLTreeTest {
    public static void main(String[] args){

        Comparator<AVLNode>myComp2 = new Comparator<AVLNode>() {
            @Override public int compare(AVLNode n1, AVLNode n2) {
                return n1.getKey().compareTo(n2.getKey());
            }
        };

        AVLNode<String, AVLNode> a1 = new AVLNode( "test3", new Cuboid (2,3,4,5,6,7) );
        AVLNode<String, AVLNode> a2 = new AVLNode( "test2", new Cuboid (2,3,4,5,6,7) );
        AVLNode<String, AVLNode> a3 = new AVLNode( "test8", new Cuboid (2,3,4,5,6,7) );
        AVLNode<String, AVLNode> a4 = new AVLNode( "test1", new Cuboid (2,3,4,5,6,7) );

        List<AVLNode> listOfNodes = new ArrayList<AVLNode>();
        listOfNodes.add(a1);
        listOfNodes.add(a2);
        listOfNodes.add(a3);
        listOfNodes.add(a4);
        Collections.sort(listOfNodes, myComp2);

        for (AVLNode node : listOfNodes){
            System.out.println(node);
        }
    }
}

这是我的AVLNode类

public class AVLNode<K, V>  {

    private AVLNode<K, V> left, right, parent;
    private int height = 1;
    private K key;
    private V value;

    public AVLNode() {}
    public AVLNode(K key, V value) {
        this.key = key;
        this.value = value;
    }


    public V getValue() {
        return value;
    }

    public K getKey() {
        return key;
    }
}

我做错了什么?

5 个答案:

答案 0 :(得分:5)

AVLNode是通用的,以KV参数化。在Comparator<AVLNode>中,AVLNode是未加工的。也就是说,KV未知。这意味着编译器实际上不知道KComparable

尝试制作Comparator<AVLNode<String, ?>>

不相关,但也使用new AVLNode<>(...)

答案 1 :(得分:4)

不要使用原始类型,最好写:

Comparator<AVLNode<Type1, Type2> comparator ...

例如:

Comparator<AVLNode<String, Cuboid>> myComp2 = new Comparator<>() {
    @Override
    public int compare(AVLNode<String, Cuboid> n1, AVLNode<String, Cuboid> n2) {
        return n1.getKey().compareTo(n2.getKey());
    }
};

顺便说一下,您可以使用Comparator.comparing(...)而不是匿名类,例如:

Comparator<AVLNode<String, Cuboid>> comparator = Comparator.comparing(AVLNode::getKey);

答案 2 :(得分:2)

K中的{p> AVLNode并未包含与Comparable的一致性(compareTo可能来自哪里)

您可以向K添加其他约束,以便所有键必须符合Comparable,类似于......

public class AVLNode<K extends Comparable<K>, V> {
    //...
}

这将限制放在AVLNode本身,所以要小心(所有键必须实现Comparable

答案 3 :(得分:1)

您在比较器中声明原始AVLNode个对象。这就是Object只有类AVLNode.getKey()的方法可用的原因。

将比较器声明更改为此

Comparator<AVLNode<String, Cuboid>> myComp2 = new Comparator<AVLNode<String, Cuboid>>() {
        @Override
        public int compare(AVLNode<String, Cuboid> o1, AVLNode<String, Cuboid> o2) {
            return 0;
        }
    };

答案 4 :(得分:1)

如上所述,编译器不知道declare nvid number := 4561; fromMot number; toMot number; begin for idx in 1..10 loop for fwd in 0..1 loop if fwd=0 then fromMot:=idx; toMot:=8; else fromMot:=8; toMot:=idx; End if; BEGIN insert into MOT_BUFFER_TIME(MBT_ID,MBT_NV_ID,MBT_START_MOT_ID,MBT_END_MOT_ID,MBT_BUFFER_TIME) values ((select max(mbt.MBT_ID)+1 from MOT_BUFFER_TIME mbt),nvid,fromMot,toMot,600); exception when dup_val_on_index then UPDATE MOT_BUFFER_TIME set MBT_BUFFER_TIME=600 where MBT_NV_ID=nvid and MBT_START_MOT_ID=fromMot and MBT_END_MOT_ID=toMot; END; end loop; end loop; end; / 返回n1.getKey(),因此它假定将返回String。无论如何,Object工作,您的代码可以通过这种方式进行修改,请参见下文。您尚未提供Collections.sort()的实施,因此我将其替换为字符串。

Cuboid

输出:

public class AVLTreeTest {

  public static void main(String[] args) {

    Comparator myComp2 = new Comparator<AVLNode>() {
      @Override
      public int compare(AVLNode n1, AVLNode n2) {
        return ((String)n1.getKey()).compareTo((String)n2.getKey());
      }
    };

    AVLNode<String, AVLNode> a1 = new AVLNode("test3", "asd");
    AVLNode<String, AVLNode> a2 = new AVLNode("test2", "bds");
    AVLNode<String, AVLNode> a3 = new AVLNode("test8", "asdfas");
    AVLNode<String, AVLNode> a4 = new AVLNode("test1", "asdfasdf");

    List<AVLNode> listOfNodes = new ArrayList<AVLNode>();
    listOfNodes.add(a1);
    listOfNodes.add(a2);
    listOfNodes.add(a3);
    listOfNodes.add(a4);
    Collections.sort(listOfNodes, myComp2);

    for (AVLNode node : listOfNodes) {
      System.out.println(node);
    }
  }
}

class AVLNode<K, V> {

  private AVLNode<K, V> left, right, parent;
  private int height = 1;
  private K key;
  private V value;

  public AVLNode() {
  }

  public AVLNode(K key, V value) {
    this.key = key;
    this.value = value;
  }


  public V getValue() {
    return value;
  }

  public K getKey() {
    return key;
  }

  @Override
  public String toString() {
    return "AVLNode{" +
        "left=" + left +
        ", right=" + right +
        ", parent=" + parent +
        ", height=" + height +
        ", key=" + key +
        ", value=" + value +
        '}';
  }
}

P.S。实际上,我检查了@MadProgrammer的建议。它也是这样工作的

...

AVLNode{left=null, right=null, parent=null, height=1, key=test1, value=asdfasdf}
AVLNode{left=null, right=null, parent=null, height=1, key=test2, value=bds}
AVLNode{left=null, right=null, parent=null, height=1, key=test3, value=asd}
AVLNode{left=null, right=null, parent=null, height=1, key=test8, value=asdfas}

...

Comparator myComp2 = new Comparator<AVLNode>() {
      @Override
      public int compare(AVLNode n1, AVLNode n2) {
        return n1.getKey().compareTo(n2.getKey());
      }
    };

...

编译器只需要知道您的class AVLNode<K extends Comparable<K>, V> { 实现了key

相关问题