Java 11'de genel koleksiyonun haritası [çoğalt]
Bir koleksiyonun haritasını çıkarmak için genel bir işlev yazmanın bir yolunu bulmaya çalışıyorum - muhtemelen jenerik kullanmıyorum.
Diyelim ki A'dan B'ye bir fonksiyonum var, a'yı alan Collection<A>ve a döndüren bir fonksiyon yazmak istiyorum Collection<B>. A ve B'nin jenerik olmadığını, sadece genel bir modeli ifade etmenin bir yolu olduğunu unutmayın.
Şimdiye kadar sahip olduğum şey
public static Collection<Point> points2dToPoints(Collection<Point2D> points) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(Collectors.toCollection(() -> points));
}
Bununla birlikte, içinde bir tür hatası alıyorum .collect, çünkü açıkçası yeni koleksiyonun olmasını istiyorum Collection<Point>ama bunun için nasıl bir Tedarikçi alacağımdan emin değilim?
Düzenleme: Bu işlevi genel bir şekilde kullanabilmeyi istiyorum: Bir Set'i geçersem karşılığında bir Set alırım, ancak bir Listeyi geçersem karşılığında bir liste alırım. bunu yapmak mümkün mü?
Yanıtlar
En iyi seçenek, fazla karmaşık olmamak ve basitçe şunu yapmaktır:
public static Collection<Point> points2dToPoints(Collection<Point2D> points) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(Collectors.toList());
}
Somut bir arayüz uygulamak dönen Collection( örn Collectors.toList() dışarıdan saklanırken) uygulama detayları, ( yani sahip Collectionyöntem imzası).
Bununla birlikte, yöntemin geri dönmesini istediğiniz Supplierarayüzün somut uygulamasına Collection, yani hangi somut uygulamaya geçerek yönteminizi daha genel hale getirebilirsiniz.
public static Collection<Point> points2dToPoints(Collection<Point2D> points, Supplier<Collection<Point>> aNew) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(toCollection(aNew));
Bu şekilde Collection, döndürülecek somut uygulamayı geçebilirsiniz, örneğin:
points2dToPoints(.., ArrayList::new);
points2dToPoints(.., TreeSet::new);
İfadeyi Collectors.toCollection(() -> points)ile değiştirin 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());
}
}
Çıktı:
Car [name=Toyota]
Car [name=Ford]
Car [name=Suzuki]