为不同的类实现可比较的通用链接列表

时间:2017-08-28 14:34:47

标签: java sorting comparable

首先:我不是要重新发明轮子,这是为了研究目的。

我是世界的新手,所以请耐心等待。

我的目标是构建一个公共类来管理带有排序插入的链表。

到目前为止我做的(工作)是:

import java.util.Iterator;

import package_Car.SortTypes;

class Node<E>
{
    E data;
    Node<E> next;

    Node(E data, Node<E> node)
    {
        this.data = data;
        this.next = node;
    }

    public Node<E> getNext()
    {
        return next;
    }
}

public class SortedInsertionLinkedList<E> implements Iterable<Node<E>>
{
    Node<E> root;
    Sort_Types sort;

    final class LinkedListIterator implements Iterator<Node<E>>
    {
        private Node<E> cursor;

        LinkedListIterator(Node<E> root)
        {
            cursor = new Node<E>(null, null);
            cursor = root;
        }

        public boolean hasNext()
        {       
            return cursor != null;
        }

        public Node<E> next()
        {
            Node<E> retVal = cursor;

            if (hasNext())
            {
                cursor = retVal.getNext();
            }

            return retVal;      
        }
    }   

    public Iterator<Node<E>> iterator()
    {
        return new LinkedListIterator(root);
    }

    public SortedInsertionLinkedList(Sort_Types sort)
    {
        root = null;
        this.sort = sort;
    }

    public void insert(E item)
    {
        if (item != null)
        {
            if (root == null)
            {
                root = new Node<E>(item, null);
            }
            else
            {
                Node<E> currNode = root;
                Node<E> prevNode = null;

                for (Node<E> currListNode : this) 
                {
                    if (sort.compareTo(currListNode.data, item) < 0)
                    {
                        prevNode = currListNode;
                        currNode = currListNode.next;
                    }
                }

                Node<E> t = new Node<E>(item, currNode);

                if (prevNode == null)
                    root = t;
                else
                    prevNode.next = t;

            }
        }
    }

    public void print()
    {
        for (Node<E> currNode : this)
        {
            System.out.print(currNode.data + " ");
            System.out.println();
        }
        System.out.println();
    }

    public boolean find(E x)
    {
        for (Node<E> currNode : this)
        {
            int c = sort.compareTo(currNode.data, x);

            if (c == 0)
                return true;
            if (c > 0)
                return false;
        }
        return false;
    }

    public void delete(E x)
    {
        Node<E> prevNode = null;
        for (Node<E> currNode : this)
        {
            int c = sort.compareTo(currNode.data, x);
            if (c == 0)
            {
                if (currNode == root)
                {
                    root = currNode.next;
                }
                else
                {
                    prevNode.next = currNode.next;
                }

                return;
            }
            if (c > 0)
                return;

            prevNode = currNode;
        }
    }
}

正如您所看到的,我在我的类中添加了一个私有字段,用于定义必须使用哪种类型的排序来比较链表节点。此排序类型是枚举

public enum Sort_Types
{
    SORT_BY_NAME
    {
        public int compareTo(Object o1, Object o2)
        {
            Car item1 = (Car) o1;
            Car item2 = (Car) o2;

            return item1.nome.compareTo(item2.nome);
        }
    },
    SORT_BY_PRICE
    {
        public int compareTo(Object o1, Object o2)
        {
            Car item1 = (Car) o1;
            Car item2 = (Car) o2;

            return Double.compare(item1.prezzo, item2.prezzo);
        }
    },
    SORT_BY_GAIN
    {
        public int compareTo(Object o1, Object o2)
        {
            double gain1;
            double gain2;

            if (o1 instanceof CarSpecificInterface)
            {
                CarSpecificInterface dummy = (CarSpecificInterface) o1;
                gain1 = dummy.gain();
            }
            else
            {
                throw new IllegalArgumentException();
            }

            if (o2 instanceof CarSpecificInterface)
            {
                CarSpecificInterface dummy = (CarSpecificInterface) o2;
                gain2 = dummy.gain();
            }
            else
            {
                throw new IllegalArgumentException();
            }

            return Double.compare(gain2, gain1);
        }
    },
    SORT_BY_URGENCY
    {
        public int compareTo(Object o1, Object o2)
        {
            double urgency1;
            double urgency2;

            if (o1 instanceof CarSpecificInterface)
            {
                CarSpecificInterface dummy = (CarSpecificInterface) o1;
                urgency1 = dummy.urgency();
            }
            else
            {
                throw new IllegalArgumentException();
            }

            if (o2 instanceof CarSpecificInterface)
            {
                CarSpecificInterface dummy = (CarSpecificInterface) o2;
                urgency2 = dummy.urgency();
            }
            else
            {
                throw new IllegalArgumentException();
            }        

            return Double.compare(urgency2, urgency1);
        }
    };

    public abstract int compareTo(Object o1, Object o2);
}

为什么我这样做?由于可用于实例化链表的类是3:

  1. Car
  2. New_Car extends Car
  3. Used_Car extends Car
  4. New_CarUsed_Car类实现了一个接口

    public interface Car_Specific_Interface
    {
        public double gain();
        public double urgency();
    }
    

    所以我可以将我的链表用于可以接受(显然)SubClasses

    的Car类型
    Sorted_Linked_List<Car> carsSortedByName;
    Sorted_Linked_List<Car> carSortedByGain;
    Sorted_Linked_List<Car> carSortedByUrgency;
    
    public DB_Mng()
    {
        carsSortedByName = new Sorted_Linked_List<>(Sort_Types.SORT_BY_NAME);
        carSortedByGain = new Sorted_Linked_List<>(Sort_Types.SORT_BY_GAIN);
        carSortedByGain = new Sorted_Linked_List<>(Sort_Types.SORT_BY_URGENCY);
    }
    

    所以,总结一下:我有一个带有排序插入的通用链表,可以接受不同的类,可以按特定的字段或方法排序。

    我想要了解的是,是否有办法改变班级层次结构&#34;简单地说&#34;实施Comparable接口。

3 个答案:

答案 0 :(得分:1)

我建议完全退一步。使用Java8和lambdas以及流程,2017年确实会做出不同的事情。或者说,好几年。

我建议你从2014年斯图加特Java论坛中查看这个presentation。用德语开头几句,但其余的都是代码,很容易掌握。

事情是:你想写代码如下:

collection .sort(
  Comparator
  .comparing(Person::getName)
  .reversed()
  .thenComparing(Person::getId)
);

并使用lambdas /方法引用 - 而不是编写所有“手动样板”代码来访问成员字段,例如。

答案 1 :(得分:1)

第一步是了解java泛型。 特别, java泛型是一个编译时功能; 它们绝不是c ++模板的java实现。

您无法创建“完全通用”的插入排序列表,因为Object未实现任何比较功能。

您可以创建实现某些已知接口或扩展特定类的元素的插入排序列表。

答案 2 :(得分:1)

如果NewCarUsedCar同时正在实施Car_Specific_Interface,您只需检查比较器中的界面,例如:

        if (o1 instanceof Car_Specific_Interface)
        {
            Car_Specific_Interface dummy = (Car_Specific_Interface) o1;
            gain1 = dummy.gain();
        }
        else
        {
            throw new IllegalArgumentException();
        }

您还可以让比较功能更复杂,以支持ComparableComparator。例如:

private int compareItems(E firstItem, E secondItem) {
    if (sort == null) {
        if (firstItem instanceof Comparable && secondItem instanceof Comparable) {
            return ((Comparable)firstItem).compareTo(secondItem);
        } else {
            throw new IllegalArgumentException("Failed to compare");
        }
    } 
    return sort.compareTo(firstItem, secondItem);
}