映射 Java 11 中的通用集合
Map over generic collection in Java 11
我一直在努力寻找一种方法来编写泛型函数(可能不使用泛型)来映射集合。
假设我有一个函数 A 到 B,我想编写一个接受 Collection<A>
和 return 的函数 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 传递给它,我将在 return 中得到一个 Set,但如果我将一个 List 传递给它,我将得到一个列表在 return。甚至可以这样做吗?
将语句 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]
最好的选择是不要过于复杂,简单地做:
public static Collection<Point> points2dToPoints(Collection<Point2D> points) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(Collectors.toList());
}
return接口 Collection
的具体实现(例如, Collectors.toList()
)同时向外部隐藏实现细节,( 即, 在方法签名中具有 Collection
。
但是,您可以通过传递给它来使您的方法更通用 -- 如 Supplier
-- 您希望它传递给接口 Collection
的具体实现 return,即
public static Collection<Point> points2dToPoints(Collection<Point2D> points, Supplier<Collection<Point>> aNew) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(toCollection(aNew));
通过这种方式,您可以传递将 returned 的具体 Collection
实现,例如:
points2dToPoints(.., ArrayList::new);
points2dToPoints(.., TreeSet::new);
我一直在努力寻找一种方法来编写泛型函数(可能不使用泛型)来映射集合。
假设我有一个函数 A 到 B,我想编写一个接受 Collection<A>
和 return 的函数 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 传递给它,我将在 return 中得到一个 Set,但如果我将一个 List 传递给它,我将得到一个列表在 return。甚至可以这样做吗?
将语句 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]
最好的选择是不要过于复杂,简单地做:
public static Collection<Point> points2dToPoints(Collection<Point2D> points) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(Collectors.toList());
}
return接口 Collection
的具体实现(例如, Collectors.toList()
)同时向外部隐藏实现细节,( 即, 在方法签名中具有 Collection
。
但是,您可以通过传递给它来使您的方法更通用 -- 如 Supplier
-- 您希望它传递给接口 Collection
的具体实现 return,即
public static Collection<Point> points2dToPoints(Collection<Point2D> points, Supplier<Collection<Point>> aNew) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(toCollection(aNew));
通过这种方式,您可以传递将 returned 的具体 Collection
实现,例如:
points2dToPoints(.., ArrayList::new);
points2dToPoints(.., TreeSet::new);