gpt4 book ai didi

返回不同类型泛型列表的Java方法

转载 作者:行者123 更新时间:2023-12-05 03:17:03 27 4
gpt4 key购买 nike

我目前正在尝试编写一个遍历 Ant-Objects 列表并返回 AntScouts 列表的方法,扩展 Ant 。一般来说,List<Ant>可以包含很多继承自 Ant 的不同对象。

我还有一个针对不同种类 Ant 的枚举:

public enum AntType {
QUEEN,WARRIOR,GATHERER,SCOUT;

public Class getClass(AntType type){
return switch (type) {
case QUEEN -> AntQueen.class;
case WARRIOR -> AntWarrior.class;
case GATHERER -> AntGatherer.class;
case SCOUT -> AntScout.class;
};
}
}

此枚举导致警告:

Raw use of parameterized class 'Class'

这是当前返回 List<Ant> 的方法.

public List<Ant> getAntsType(AntType type){
return ants.stream().filter(ant -> ant.getType() == type).toList();
}

我怎样才能编写方法使其获得 AntType枚举作为参数并返回 List<AntScout>List<AntWarrior>对应枚举?我真的不想用 Class<T> clazz 作为参数,因为这会破坏枚举的重点。 (我也在别处使用那个枚举,所以我无法摆脱它)

我如何编写该方法以便它获取 AntType 枚举作为参数并返回一个列表或与该枚举对应的列表?

编辑:此评论可能最接近所需的解决方案: Java Method that returns different types of generic Lists

最佳答案

利用多态的力量

How can I write the method so that it get's the AntType enum as argument and returns a List or List corresponding to the enum?

您无缘无故地过度设计了代码。

当您使用继承时,您的类的设计方式应允许从 Polymorphism 中获益.

即通过使用 super 类型 Ant为您的所有对象并通过覆盖行为与它们交互,而无需区分具体实现和通过类型转换进行操作。

因此,您的方法返回 List<Ant>很好。

即使你想获得 List<AntQueen>List<AntScout>作为方法执行的结果,您将需要使用通用类型变量 T ,或者更确切地说 T extends Ant ,这意味着您需要一种表示 T 的方法.和 enum不会帮助您完成此任务,因为在 Java 中枚举不能是通用的。您需要提供一个 T 的实例作为方法参数或 Class<T> .

public <T extends Ant> List<T> getAntsByType(Class<T> tClass) {
return ants.stream().filter(tClass::isAssignableFrom).toList();
}

但我建议坚持使用返回父类(super class)型列表 Ant 的初始版本报关方式getType()它返回枚举的实例 AntType .

public List<Ant> getAntsByType(AntType type) {
return ants.stream().filter(ant -> ant.getType() == type).toList();
}

正如我所说,Java 枚举不能是通用的,没有办法获得 Class<T>通过这。因此,您可以删除人为的方法 getClass()来自 AntType .

public enum AntType {
QUEEN, WARRIOR, GATHERER, SCOUT;
}

模拟 self 类型

但是如果您仍然确信您的应用程序逻辑需要能够生成一个具体类型的列表,例如 List<AntScout>从父类(super class)型列表中,然后您可以使用递归类型绑定(bind)。

为此,您需要将父类(super class)型定义为 Ant<T extends Ant<T>> .

这种方法也称为模拟自类型习语,可以在所有枚举的父类型声明中观察到 java.lang.Enum<E extends Enum<E>>以及 JDK 的其他一些部分,例如方法 Collections.sort(List<T>) 其中 T定义为 <T extends Comparable<? super T>> .

让我们在这种情况下应用自类型习语。

考虑父类(super class)型 Ant定义为一个接口(interface),声明一个自返回方法(如果需要声明一些骨架实现和公共(public)字段,可以改为抽象类):

interface Ant<T extends Ant<T>> {
T self();
AntType getType();
}

这里有几个具体类:

public static class AntWarrior implements Ant<AntWarrior> {

@Override
public AntWarrior self() {
return this;
}

@Override
public AntType getType() {
return AntType.WARRIOR;
}
}

public static class AntScout implements Ant<AntScout> {
@Override
public AntScout self() {
return this;
}

@Override
public AntType getType() {
return AntType.SCOUT;
}
}

我们如何使用 self() 执行转换方法:

@SuppressWarnings("unchecked")
public static <T extends Ant<T>> List<T> getAntsByType(List<Ant<?>> ants,
AntType type) {
return ants.stream()
.filter(ant -> ant.getType() == type)
.map(ant -> (T) ant.self())
.toList();
}

使用示例:

public static void main(String[] args) {
List<Ant<?>> ants = List.of(new AntWarrior(), new AntScout());

// compiles and runs without issues
List<AntWarrior> antWarriors = getAntsByType(ants, AntType.WARRIOR);
System.out.println(antWarriors);

// compiles and runs without issues
List<AntScout> antScouts = getAntsByType(ants, AntType.SCOUT);
System.out.println(antScouts);
}

输出:

[AntWarrior{}]
[AntScout{}]

A link to Online Demo

关于返回不同类型泛型列表的Java方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74353528/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com