Java如何比较泛型类型?
下面是通用二进制搜索树的代码。现在,它运行和编译都很完美,但有一个问题我只是在完成这门课之后才注意到。问题是insert方法使用compareTo()(在比较节点的元素时)根据其“值”来决定在树中放置下一个节点的位置。例如,对于以下输入: 1112,2 而不是得到这棵树:Java如何比较泛型类型?,java,oop,generics,Java,Oop,Generics,下面是通用二进制搜索树的代码。现在,它运行和编译都很完美,但有一个问题我只是在完成这门课之后才注意到。问题是insert方法使用compareTo()(在比较节点的元素时)根据其“值”来决定在树中放置下一个节点的位置。例如,对于以下输入: 1112,2 而不是得到这棵树: 1 \ 2 \ 112 我最终得到的是: 1 \ 2 / 112 因为比较
1
\
2
\
112
我最终得到的是:
1
\
2
/
112
因为比较可能是以词典的方式进行的,所以它可以看到2>112
下面是树类的代码:
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.*;
导入java.io.*;
导入java.lang.*;
公共类树
{私有节点根=null;
静态字符串S=“”;
公树()
{File File=新文件(“date.in.txt”);
尝试
{扫描仪输入=新扫描仪(文件);
while(input.hasNext())
插入((T)input.next();}
捕获(FileNotFoundException ex)
{System.out.printf(“错误:%s!\n”,ex);}
public void show(){printLevelOrder(maxDepth());}
public void printLevelOrder(整数深度)
{for(int i=1;i 1)
{String leftStr=printLevel(t.left,level-1);
String rightStr=打印级别(t.right,级别-1);
返回leftStr+rightStr;}
其他的
返回“”;}
int maxDepth(){返回maxDepth2(根);}
int maxDepth2(节点)
{if(node==null)
返回(0);
其他的
{int leftDepth=maxDepth2(node.left);
int rightDepth=maxDepth2(node.right);
如果(leftDepth>rightDepth)
返回(leftDepth+1);
其他的
返回(rightDepth+1);}
公共字符串toString(){返回this.inoorder();}
公共字符串InOrder(){inOrder2(根);返回S;}
public void inOrder2(节点根)
{if(root!=null)
{inOrder2(root.left);
S=S+root.element+“”;
inOrder2(root.right);}
公共布尔插入(T元素)//I N S E R T M E T H O D
{if(isEmpty())
{root=新节点(元素);
返回true;}
节点电流=根;
节点父节点;
做
{父=当前;
if(element.compareTo(current.element)0)
current=current.right;
其他的
返回false;}
while(当前!=null);
节点=新节点(元素);
if(element.compareTo(parent.element)>0)
parent.right=节点;
其他的
parent.left=节点;
返回true;}
公共布尔isEmpty(){return root==null;}
私有静态类节点
{Node left=null;
Node right=null;
最终T元素;
节点(T元素){this.element=element;}}
主要内容如下:
import java.util.*;
import java.io.*;
public class Main
{public static void main(String[]args)
{Tree <Double> T=new Tree<>(); } }
import java.util.*;
导入java.io.*;
公共班机
{公共静态void main(字符串[]args)
{Tree T=new Tree();}}
现在我做了一些研究,四处询问,我听说了一个叫做comparator的东西,但我以前没有使用过,我不知道如何实现它。现在,如果您有任何解决方案来解决这个问题,或者添加/执行什么操作,我将全力以赴。您的行insert((T)input.next())
没有意义-输入。next()
是一个字符串
,但您正在将其强制转换为t
,即使此时t
与实际类型没有关联。例如,在构造树时,调用方可以说新建树
生成该行,本质上是插入((整数)input.next())代码>,已断开
如果您的目标是使树
始终包含字符串
s,只需从树
中删除泛型T
类型,然后使用字符串
。如果您确实希望支持任意类型,则需要将文件读取行为移出树
构造函数(例如,进入返回树
的静态方法)
例如:
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;
}
}
将避免强制调用方处理异常
现在我们已经清理了树
类型,您的排序问题可能更容易回答。如果要将元素排序为整数,请将输入转换为整数,例如
public static Tree<Integer> readIntsFromFile(Path file) throws FileNotFoundException {
...
tree.insert(Integer.valueOf(input.next()));
...
}
公共静态树readIntsFromFile(路径文件)引发FileNotFoundException{
...
insert(Integer.valueOf(input.next());
...
}
这将基于整数排序而不是字符串的字典排序对树进行排序。这就是我建议你做的。这很简单,而且做你想做的事
如果你真的想要一个树
,但你想把它们当作整数来排序,你需要一个定制,就像你提到的那样。然后您需要将比较器
传递到树的构造函数中,并调用比较器.compare(element,current.element)
当前调用element.compareTo(current.element)
的地方,词典比较将放入1<112,因此这不是正在发生的事情(或者不是所有正在发生的事情)。此外,如果T是整数,则compareTo将不是字典式比较,如果T是字符串,则需要停止将整数存储为字符串,并将T设为整数。比较器几乎肯定不是正确的解决方案。@user2357112现在我意识到我的画做错了。我重新做了,结果就是这样。112@user2357112所以你看起来像是一个了解自己的东西的人,有什么想法吗?请发布一个完整的示例,带有main方法,很好,它可以工作,但是如果我将树声明为:tree T,然后继续给出双值作为输入,那么我会将java.lang.Nu
public static Tree<Integer> readIntsFromFile(Path file) throws FileNotFoundException {
...
tree.insert(Integer.valueOf(input.next()));
...
}