[英]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.