在Java中,如何为扩展comparator的类实现多个comparator方法?
我有一个通用的AVL树实现,Node类扩展了comparator,我希望将一个对象作为节点传递,并能够选择comparator将与之进行比较的属性
我的对象的类实现并重写了comparator方法,但我已经硬编码了用于比较的属性
我尝试过的事情:
- 创建多个comparator方法,但我只能用其中一个覆盖comparator李>
- 重载比较器方法,也不起作用
做这件事最好的方法是什么
我的节点类:
package compare;
import java.util.Comparator;
public class Node<T extends Comparator<T>> {
int depth;
int level;
Node<T> left, right;
T data;
Node(T data) {
this(data, null, null);
}
Node(T data, Node<T> left, Node<T> right){
super();
this.data = data;
this.left = left;
this.right = right;
if (left == null && right == null)
setDepth(1);
else if (left == null)
setDepth(right.getDepth() + 1);
else if (right == null)
setDepth(left.getDepth() + 1);
else
setDepth(Math.max(left.getDepth(), right.getDepth()) + 1);
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public Node<T> getLeft() {
return left;
}
public void setLeft(Node<T> left) {
this.left = left;
}
public Node<T> getRight() {
return right;
}
public void setRight(Node<T> right) {
this.right = right;
}
/**
* @return the depth
*/
public int getDepth() {
return depth;
}
/**
* @param depth
* the depth to set
*/
public void setDepth(int depth) {
this.depth = depth;
}
public int comp(Node<T> o, T o2) {
return this.data.compare(o.getData(),o2);
}
@Override
public String toString() {
return "Level " + level + ": " + data;
}
}
AVL树类:
package compare;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Queue;
class AVLTree<T extends Comparator<T>> {
Node<T> root;
AVLTree(){
root = null;
}
T Maximum() {
Node<T> local = root;
if (local == null)
return null;
while (local.getRight() != null)
local = local.getRight();
return local.getData();
}
T Minimum() {
Node<T> local = root;
if (local == null)
return null;
while (local.getLeft() != null) {
local = local.getLeft();
}
return local.getData();
}
private int depth(Node<T> node) {
if (node == null)
return 0;
return node.getDepth();
}
Node<T> insert(T data) {
root = insert(root, data);
switch (balanceNumber(root)) {
case 1:
root = rotateLeft(root);
break;
case -1:
root = rotateRight(root);
break;
default:
break;
}
return root;
}
Node<T> insert(Node<T> node, T data) {
if (node == null)
return new Node<T>(data);
if (node.comp(node,data)>0) {
node = new Node<T>(node.getData(), insert(node.getLeft(), data), node.getRight());
} else if (node.comp(node,data)<0) {
node = new Node<T>(node.getData(), node.getLeft(), insert(node.getRight(), data));
}
// After insert, balance tree.
switch (balanceNumber(node)) {
case 1:
node = rotateLeft(node);
break;
case -1:
node = rotateRight(node);
break;
default:
return node;
}
return node;
}
private int balanceNumber(Node<T> node) {
int L = depth(node.getLeft());
int R = depth(node.getRight());
if (L - R >= 2)
return -1;
else if (L - R <= -2)
return 1;
return 0;
}
private Node<T> rotateLeft(Node<T> node) {
Node<T> q = node;
Node<T> p = q.getRight();
Node<T> c = q.getLeft();
Node<T> a = p.getLeft();
Node<T> b = p.getRight();
q = new Node<T>(q.getData(), c, a);
p = new Node<T>(p.getData(), q, b);
return p;
}
private Node<T> rotateRight(Node<T> node) {
Node<T> q = node;
Node<T> p = q.getLeft();
Node<T> c = q.getRight();
Node<T> a = p.getLeft();
Node<T> b = p.getRight();
q = new Node<T>(q.getData(), b, c);
p = new Node<T>(p.getData(), a, q);
return p;
}
public boolean search(T data) {
Node<T> local = root;
while (local != null) {
if (local.getData().compare(local.getData(), data) == 0)
return true;
else if (local.getData().compare(local.getData(), data) > 0)
local = local.getLeft();
else
local = local.getRight();
}
return false;
}
public String toString() {
return root.toString();
}
public void PrintTree() {
root.level = 0;
Queue<Node<T>> queue = new LinkedList<Node<T>>();
queue.add(root);
while (!queue.isEmpty()) {
Node<T> node = queue.poll();
System.out.println(node);
int level = node.level;
Node<T> left = node.getLeft();
Node<T> right = node.getRight();
if (left != null) {
left.level = level + 1;
queue.add(left);
}
if (right != null) {
right.level = level + 1;
queue.add(right);
}
}
}
}
驱动程序代码:
public static void main(String[] args) throws IOException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
// TODO Auto-generated method stub
String pathToCsv = "data_tiny.csv";
ArrayList<HDTestData<?>> HDlist = readFromCSV(pathToCsv);
AVLTree<HDTestData<?>> tree1 = new AVLTree<>();
for(int i=0; i<HDlist.size(); i++) {
// adding elements to tree
tree1.insert(HDlist.get(i));
}
tree1.PrintTree();
}
我有一个HDTestData对象的Arraylist,如下所示:
package compare;
import java.util.Comparator;
public class HDTestData<T> implements Comparator<HDTestData<T>>{
String serial, model, capacity, powerOnHours;
HDTestData (String serial, String model, String capacity, String powerOnHours){
this.serial = serial;
this.model = model;
this.capacity = (capacity);
this.powerOnHours = (powerOnHours);
}
@Override
public int compare(HDTestData<T> o1,HDTestData<T> o2) {
int one = Integer.parseInt(o1.powerOnHours);
int two = Integer.parseInt(o2.powerOnHours);
if(one>two) {
return 1;
}
if(one == two) {
return 0;
}
return -1;
}
@Override
public String toString() {
String output = this.serial+", "+this.model+", "+this.capacity+", "+this.powerOnHours;
return output;
}
public String getSerial() {
return serial;
}
public void setSerial(String serial) {
this.serial = serial;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getCapacity() {
return capacity;
}
public void setCapacity(String capacity) {
this.capacity = capacity;
}
public String getPowerOnHours() {
return powerOnHours;
}
public void setPowerOnHours(String powerOnHours) {
this.powerOnHours = powerOnHours;
}
}
我的HDtestData中的compare方法是通过“PowerOnHours”进行比较的,我希望能够在构建AVLTree对象时选择它正在使用的属性
# 1 楼答案
Comparator
是一个只有一个实例方法签名的接口,即所谓的“功能接口”。如果需要多种比较对象的方法,则需要实现多个比较器。例如:(如果您不喜欢lambdas,可以在方便的时候使用命名类或匿名类。)
为了使树实现工作,它需要是通用的w.r.t.比较器,例如:
旁白:老实说,我认为类型定义
T extends Comparator<T>
没有多大意义。可以编写这样的类,但是上面的HDTestData::compareTo
方法没有引用this
,因此没有必要将其放在同一个类中