[英]Java generics for optional single value or collection
我正在尝试为整个类定义一个容器,因为代码的某些部分对集合更有意义,而其他地方对单个值才有意义。
理想情况下,我想这样做:
public class AllModes<T> {
private T<Car> car;
private T<Boat> boat;
private T<Train> train;
private T<Plane> plane;
...40 more of these...
}
然后我想使用类似的类:
AllModes<List> allModes;
AllModes<Optional> oneOfEachMode;
但是我得到的错误是“类型T不是通用的;不能使用参数对其进行参数化”
我要在多个变量中而不是在基于超类的单个HashSet中定义它们的原因是,我希望有返回正确类型的get方法,以避免此类的使用者需要在任何地方进行转换,因为每个对象都有自己的不同字段。
我还考虑过仅存储单个值列表或集合,但我认为使用我想要的正确类型(即一个值)可能会减少出错的可能性
您无法通过这种方式解决。 改用instanceof
运算符。 这是一个例子:
public class AllModes<T> {
private T object;
private void check(T object) {
if(object instanceof Boat){
System.out.println("Boat");
// your code for Boat goes here
} else if (object instanceof Car) {
System.out.println("Car");
// your code for Car goes here
}
}
}
来自Java™教程-为什么使用泛型? :
通过使用泛型,程序员可以实现对不同类型的集合工作的泛型算法,可以对其进行自定义,并且类型安全且易于阅读。
您可以在类中具有多种类型,然后可以将它们与字段关联。 但是在您的情况下,您有几个具有某些类型的字段。 一个类对其他人没有太多依赖。 您应该以没有太多依赖关系的方式设计类。
public class AllModes<T,T1,T2,T3> {
private T car;
private T1 boat;
private T2 train;
private T3 plane;
}
使用Java类型系统无法实现所需的功能。 由于您不能具有通用的容器类型,因此需要使用专用的构造函数(或子类)强制执行不变式。
但是,如果这样做,您的类的客户端将无法区分不同的容器类型( Optional
与List
),他们将需要使用通用抽象(如Stream
, Iterator
, Iterable
,任何适合您的容器)。
这是一个例子:
public class AllModes {
private final Supplier<Stream<Car>> cars;
private final Supplier<Stream<Boat>> boats;
public AllModes(Optional<Car> car, Optional<Boat> boat) {
// Assuming Java 8, when Optional did not have a stream() method yet
this.cars = () -> car.map(Stream::of).orElse(Stream.empty());
this.boats = () -> boat.map(Stream::of).orElse(Stream.empty());
}
public AllModes(List<Car> cars, List<Boat> boats) {
this.cars = cars::stream;
this.boats = boats::stream;
}
public Stream<Car> getCars() {
return cars.get();
}
public Stream<Boat> getBoats() {
return boats.get();
}
}
我建议您退后一步,重新考虑使用此容器要实现的目标。 例如,问问自己它的域是什么,或者客户端应该使用Allmodes<T>
做什么...
想到的另一个更具体的问题是,您打算如何精确地泛泛显示Optional<T>
? 它是List<T>
的第一个元素还是最后一个? 还是满足特定Predicate<T>
的元素?
您的设计似乎还没有经过深思熟虑。
您可以做的将接近您所描述的(如果我正确的话)的是提供Stream<T>
类型的访问器,因为您可以从中获取List<T>
和Optional<T>
。 然后,您的客户将不得不做出决定,并确定如何精确地从Stream<T>
派生Optional<T>
Stream<T>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.