Java 11의 일반 컬렉션에 대한 매핑 [중복]
나는 제네릭을 사용하지 않는 제네릭 함수를 작성하여 컬렉션을 매핑하는 방법을 찾으려고 노력해 왔습니다.
A에서 B까지의 함수가 있다고 가정 해 보겠습니다 . a를 받아서 a 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>
하지만 공급자를 얻는 방법을 잘 모르겠 기 때문입니다.
편집 :이 함수를 일반적인 방식으로 사용할 수 있기를 원합니다. 세트를 전달하면 세트가 반환되지만 목록을 전달하면 목록이 반환됩니다. 이것이 가능합니까?
답변
The best option is to not overcomplicate, and simply do:
public static Collection<Point> points2dToPoints(Collection<Point2D> points) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(Collectors.toList());
}
returning a concrete implement of interface Collection
(e.g., Collectors.toList()
) while hiding from the outside the implementation details, (i.e., having Collection
in the method signature).
You can, however, make your method more generic by passing to it -- as Supplier
-- which concrete implementation of the interface Collection
you want it to return, namely
public static Collection<Point> points2dToPoints(Collection<Point2D> points, Supplier<Collection<Point>> aNew) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(toCollection(aNew));
In this way you can pass the concrete Collection
implementation that will be returned, for example:
points2dToPoints(.., ArrayList::new);
points2dToPoints(.., TreeSet::new);
Replace the statement Collectors.toCollection(() -> points)
with Collectors.toList()
.
Demo:
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());
}
}
Output:
Car [name=Toyota]
Car [name=Ford]
Car [name=Suzuki]