在Java 11中映射泛型集合



我一直在试图找到一种方法来编写一个泛型函数——可能不使用泛型——来映射集合。

假设我有一个函数a到B,我想写一个接受Collection<A>并返回Collection<B>的函数。注意,A和B不是泛型,只是表示一般模式的一种方式。

到目前为止,我拥有的是

public static Collection<Point> points2dToPoints(Collection<Point2D> points) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(Collectors.toCollection(() -> points));
}

然而,我在.collect中遇到了一个类型错误,因为很明显,我希望新集合是Collection<Point>,但我不确定如何获得供应商?

编辑:我希望能够以一种通用的方式使用这个函数:如果我传递给它一个Set,我会得到一个Set作为回报,但如果我传递它一个List,我会获得一个List作为回报。这样做可能吗?

最好的选择是不要过于复杂,只需执行:

public static Collection<Point> points2dToPoints(Collection<Point2D> points) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(Collectors.toList());
}

返回接口Collection的具体实现(例如,Collectors.toList()(,同时向外部隐藏实现细节(即,在方法签名中具有Collection(。

然而,您可以通过将您希望返回的接口Collection的具体实现(即(传递给它(作为Supplier(,使您的方法更加通用

public static Collection<Point> points2dToPoints(Collection<Point2D> points, Supplier<Collection<Point>> aNew) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(toCollection(aNew));

通过这种方式,您可以传递将返回的具体Collection实现,例如:

points2dToPoints(.., ArrayList::new);
points2dToPoints(.., TreeSet::new);

将语句Collectors.toCollection(() -> points)替换为Collectors.toList()

演示:

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
class Car {
String name;
public Car(String name) {
this.name = name;
}
@Override
public String toString() {
return "Car [name=" + name + "]";
}
}
class Book {
Car car;
public Book(Car car) {
this.car = car;
}
public Car getCar() {
return car;
}
}
public class Main {
public static void main(String[] args) {
// Test
Collection<Car> list = points2dToPoints(
List.of(new Book(new Car("Toyota")), new Book(new Car("Ford")), new Book(new Car("Suzuki"))));
list.forEach(System.out::println);
}
public static Collection<Car> points2dToPoints(Collection<Book> points) {
return points.stream().map(Book::getCar).collect(Collectors.toList());    
}
}

输出:

Car [name=Toyota]
Car [name=Ford]
Car [name=Suzuki]

最新更新