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