繁体   English   中英

可选单值或集合的Java泛型

[英]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类型系统无法实现所需的功能。 由于您不能具有通用的容器类型,因此需要使用专用的构造函数(或子类)强制执行不变式。

但是,如果这样做,您的类的客户端将无法区分不同的容器类型( OptionalList ),他们将需要使用通用抽象(如StreamIteratorIterable ,任何适合您的容器)。

这是一个例子:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM