有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在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) 个答案

  1. # 1 楼答案

    Comparator是一个只有一个实例方法签名的接口,即所谓的“功能接口”。如果需要多种比较对象的方法,则需要实现多个比较器。例如:

    Comparator<HDTestData> p = Comparator.comparing( t -> Integer.valueOf(t.getPowerOnHours()));
    Comparator<HDTestData> s = Comparator.comparing( HDTestData::getSerial );
    

    (如果您不喜欢lambdas,可以在方便的时候使用命名类或匿名类。)

    为了使树实现工作,它需要是通用的w.r.t.比较器,例如:

    class AVLTree<T, Comparator<T>> {
        Node<T> root;
        Comparator<T> comp;
        AVLTree( Comparator<T> aComp ){
            comp = aComp;
        }
    ...
        Node<T> insert(Node<T> node, T data) {
        if (comp.compare(node.getData(),data)>0) {
    ...
    

    旁白:老实说,我认为类型定义T extends Comparator<T>没有多大意义。可以编写这样的类,但是上面的HDTestData::compareTo方法没有引用this,因此没有必要将其放在同一个类中