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

Java 为不同类的通用链表实现可比较,java,sorting,comparable,Java,Sorting,Comparable,首先:我不是想重新发明轮子,这是为了学习 我是个新手,所以要有耐心 我的目标是构建一个公共类来管理带有排序插入的链表 到目前为止,我所做的(正在工作)是: 我为什么这么做?由于可用于建立链表的类有3个: Car 新车它扩展了汽车 二手车它扩展了汽车 新车和二手车类实现一个接口 public interface Car_Specific_Interface { public double gain(); public double urgency(); } 所以我可以用我的链表来

首先:我不是想重新发明轮子,这是为了学习

我是个新手,所以要有耐心

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

到目前为止,我所做的(正在工作)是:

我为什么这么做?由于可用于建立链表的类有3个:

  • Car
  • 新车
    它扩展了汽车
  • 二手车
    它扩展了汽车
  • 新车
    二手车
    类实现一个接口

    public interface Car_Specific_Interface
    {
        public double gain();
        public double urgency();
    }
    
    所以我可以用我的链表来表示可以接受(显然)子类的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);
    }
    
    按名称排序的链接列表;
    已排序的链接列表carSortedByGain;
    已排序的链接列表carSortedByUrgency;
    公共数据库
    {
    carsSortedByName=新排序的链接列表(排序类型。按名称排序);
    carSortedByGain=新排序的链接列表(排序类型。按增益排序);
    carSortedByGain=新排序的链接列表(排序类型。按紧急程度排序);
    }
    
    总之,我有一个带有排序插入的通用链表,它可以接受不同的类,并且可以按特定的字段或方法排序


    我想了解的是,是否有一种方法可以“简单地”改变类层次结构,实现
    可比较的
    接口。

    我建议完全回到这里。2017年,通过Java8、lambdas和streams,我们的工作方式确实有所不同。好吧,从几年前开始

    我建议您在2014年斯图加特Java论坛上了解这一点。有几个德语起始词,其余的都是代码,很容易掌握

    问题是:您希望编写如下代码:

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

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

    第一步是理解java泛型。 明确地 java泛型是编译时特性; 它们绝不是C++模板的java实现。 您无法创建按插入列表排序的“完全通用”,因为对象未实现任何比较功能


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

    如果
    NewCar
    UsedCar
    都在实现
    Car\u特定接口
    ,您可以在比较器中检查接口,如:

            if (o1 instanceof Car_Specific_Interface)
            {
                Car_Specific_Interface dummy = (Car_Specific_Interface) o1;
                gain1 = dummy.gain();
            }
            else
            {
                throw new IllegalArgumentException();
            }
    
    您还可以使比较函数更复杂,以支持
    Comparable
    Comparator
    。例如:

    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);
    }
    

    不要使用和枚举来实现策略模式。使用枚举识别策略是有意义的;也许将每个排序的实现作为值,并使用枚举作为键。@DwB Ok,但如何在通用链表中使用它?每个节点仅对超级类
    汽车
    有参考。如何参考正确的比较方法?显然,我更愿意避免在基于排序类型的
    插入方法中使用
    开关
    。不要把它用在其他名字上。在Java中,变量名的大小写相同。因此,您可以使用
    carsortedbyname
    而不是
    List\u Car\u Sort\u name
    @GhostCat th,我会记住它。我的(坚实的)背景有助于……;)@你最好这样做。你看,在错误的地方放置下杆会导致有经验的Java程序员患眼癌和脑损伤,而且你肯定不会有意伤害这里的任何人,对吧?;-)我已经知道Comparator类(不太了解Lambdas),但正如我所写的,我正在做一些案例研究,以更好地理解层次结构和泛型类。顺便说一句,谢谢你的链接文件。我来看看。关于接口的第一个建议很好:我没看到。大约在第二天,我需要一些时间来更好地理解这个想法……;)+1考虑到接口建议,我更新了问题代码。我实际上喜欢lambda的答案,但我不喜欢lambda。
            if (o1 instanceof Car_Specific_Interface)
            {
                Car_Specific_Interface dummy = (Car_Specific_Interface) o1;
                gain1 = dummy.gain();
            }
            else
            {
                throw new IllegalArgumentException();
            }
    
    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);
    }