簡體   English   中英

使用Comparator和Java中的對象列表

[英]Using Comparator with List of Objects in Java

我想通過鍵(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;
    }
}

我究竟做錯了什么?

AVLNode是通用的,用KV參數化。 Comparator<AVLNode>AVLNode是原始的。 也就是說, KV是未知的。 這意味着編譯器實際上不知道K是否為Comparable

嘗試使它成為Comparator<AVLNode<String, ?>>

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

不要使用原始類型,最好寫:

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);

AVLNode中的K不包含與Comparable的一致性(來自compareTo來源)

您可以向K添加一個額外的約束,以便所有鍵必須符合Comparable ,類似於......

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

這將限制放在AVLNode本身,所以要小心(所有鍵必須實現Comparable

您在比較器中聲明原始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;
        }
    };

如上所述,編譯器不知道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 +
        '}';
  }
}

輸出:

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}

PS實際上,我檢查了@MadProgrammer的建議。 它也以這種方式工作

...

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實現Comparable

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM