簡體   English   中英

Java-如何比較泛型類型?

[英]Java-How do I compare generic types?

這是通用二進制搜索樹的代碼。 現在,它可以完美運行並編譯,但是在完成本課后,我才注意到一個問題。 問題在於,insert方法使用compareTo()(在比較節點元素時)根據其值決定將下一個節點放置在樹中的位置。 例如,輸入:

1,112,2

而不是得到這棵樹:

 1  
  \   
    2    
     \    
     112

我最終得到的是:

       1
         \
          2
         / 
        112

因為比較可能是按字典順序進行的,所以它看到2> 112。

這是Tree類的代碼:

import java.util.*;
import java.io.*;
import java.lang.*;

public class Tree<T extends Comparable<T>>
    { private Node<T> root = null;
    static String S="";

    public Tree()
        {File file=new File("date.in.txt");

            try 
            { Scanner input = new Scanner( file );
            while(input.hasNext())
                 insert((T)input.next());} 

            catch (FileNotFoundException ex) 
                { System.out.printf("ERROR: %s!\n", ex); } }


    public void show(){ printLevelOrder(maxDepth()); }

    public void printLevelOrder(int depth) 
        { for (int i = 1; i <= depth; i++) 
            { System.out.print("Level " + (i-1) + ": ");
            String levelNodes = printLevel(root, i);
            System.out.print(levelNodes + "\n"); } }

    public String printLevel(Node<T> t, int level) 
        { if (t == null) 
            return "";
        if (level == 1) 
            return t.element + " ";
         else if (level > 1) 
            { String leftStr = printLevel(t.left, level - 1);
            String rightStr = printLevel(t.right, level - 1);
            return leftStr + rightStr; }
        else 
          return ""; }


    int maxDepth(){ return maxDepth2(root); }

    int maxDepth2(Node<T> node) 
        { if (node == null) 
            return (0);
         else 
            { int leftDepth = maxDepth2(node.left);
            int rightDepth = maxDepth2(node.right);

            if (leftDepth > rightDepth )
                return (leftDepth + 1);
            else
                return (rightDepth + 1); } }


    public String toString(){ return this.InOrder(); }


    public String InOrder(){ inOrder2(root); return S; }

    public void inOrder2(Node<T> root) 
        { if(root !=  null)   
            { inOrder2(root.left);    
            S=S+root.element+" ";  
            inOrder2(root.right); } }


    public boolean insert(T element)  // I N S E R T    M E T H O D
        { if (isEmpty()) 
            { root = new Node<T>(element);
            return true; }

         Node<T> current = root; 
         Node<T> parent;         

         do 
            { parent = current;

             if (element.compareTo(current.element)<0) 
                 current = current.left; 
              else if (element.compareTo(current.element)>0) 
                 current = current.right; 
              else 
                 return false; } 
             while (current != null);

         Node<T> node = new Node<T>(element);


             if ( element.compareTo(parent.element)>0  ) 
                 parent.right = node;
          else 
             parent.left = node;

         return true; } 


    public boolean isEmpty() { return root == null; }


    private static class Node<T extends Comparable<T>>   
        { Node<T> left  = null;
        Node<T> right = null;
        final T element;

        Node(T element) { this.element = element; } } }

這是主要的:

import java.util.*;
import java.io.*;

public class Main 
    {public static void main(String[]args)
        {Tree <Double> T=new Tree<>(); } }

現在,我做了一些研究,並在這里和那里問了一些,我有點喜歡比較器,但是我以前還沒有用過,所以我不確定如何實現它。 現在,如果您對如何解決此問題或添加/執行操作有任何解決方案,那么我就是耳目一新。

您的行insert((T)input.next()); 沒道理input.next()String ,但是您現在將其強制轉換為T即使此時T與實際類型都不相關。 例如,在構造Tree ,調用者可以說new Tree<Integer>進行該行,本質上是insert((Integer)input.next()); ,它已損壞。

如果您的目標是讓Tree始終包含String ,則只需從Tree刪除通用T類型,然后使用String 如果您實際上想支持任意類型,則需要將文件讀取行為移出Tree構造函數(例如,移到返回Tree<String>的靜態方法中)。

例如:

public static Tree<String> readFromFile(Path file) throws FileNotFoundException {
  try (Scanner input = new Scanner(file)) {
    Tree<String> tree = new Tree<>();
    while(input.hasNext()) {
      tree.insert(input.next());
    }
    return tree;
  }
}

請注意,我使用Path而不是File ,使用try-with-resources模式,並且我不抑制異常,而是調用方(可能是main方法)應正確處理異常(可能是通過報告文件不存在)然后退出)。 或者像這樣添加一個catch塊:

catch (IOException e) {
  throw new RuntimeException("Could not open " + file, e);
}

避免強迫調用者處理該異常。


現在我們已經清理了Tree類型,您的訂購問題可能更容易回答。 如果打算將元素排序為整數,則將輸入轉換為Integers,例如

public static Tree<Integer> readIntsFromFile(Path file) throws FileNotFoundException {
  ...
  tree.insert(Integer.valueOf(input.next()));
  ...
}

這將根據整數順序而不是字符串的字典順序對樹進行排序。 這就是我建議你做的。 它很簡單,可以做您想要的。


如果您確實想要Tree<String>但想要整數一樣對它們進行排序,則需要一個自定義的Comparator ,如上所述。 然后,您需要將Comparator傳遞到Tree的構造函數中,並在當前調用element.compareTo(current.element)地方調用element.compareTo(current.element) comparator.compare(element, current.element) element.compareTo(current.element)

暫無
暫無

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

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