[英]Java generics and streams
我正在構建一種框架以避免重復代碼,在某些時候我需要將對象Foo列表轉換為對象Bar列表。
我有擴展的數據庫實體
public class BaseEntity {...}
和擴展的表示對象
public class BaseDTO<T extends BaseEntity> {...}
所以
public class Foo extends BaseEntity {...}
和
public class Bar extends BaseDTO<A extends BaseEntity> {
public Bar(Foo entity, Locale l) {
...
}
}
現在,使用流將Foo列表轉換為Bar列表很容易
public abstract ClassThatUsesFooAndBar() {
public List<Bar> convertFooToBar(List<Foo> list) {
return list.stream().map(f -> new Bar(f, locale)).collect(...);
}
}
但是,這就是問題,這些Foo和Bar實際上是泛型(A和B),所以使用Foo和Bar的類實際上是ClassThatUsesAandB<A extends BaseEntity, B extends BaseDTO>
,因此該函數也必須是抽象的實現為具有正確A和B實現的樣板代碼,因為顯然您無法實例化泛型類型。
有沒有辦法使用泛型/流/ lambdas來創建一個可以寫一次的函數,以便實現類不需要重新實現它? 功能簽名將是
public List<B> convertAToB(List<A> list);
我希望我已經足夠清楚我需要的東西,如果你需要進一步的解釋請問
謝謝!
我認為最簡單的方法是使用lambdas進行轉換。
public static <A,B> List<B> convertList(List<A> list, Function<A,B> itemConverter) {
return list.stream().map(f -> itemConverter.apply(f)).collect(...);
}
然后你可以像這樣使用它:
List<Bar> l = convertList(fooList,foo -> new Bar(foo.getBaz()));
或者,如果您願意,可以在自己的命名類中提取它:
public class Foo2BarConverter implements Function<Foo,Bar> {
@Override
public Bar apply(Foo f) {
return new Bar(f.getBaz());
}
}
順便說一下,考慮到我們可以用流做什么,創建一個新列表似乎有點浪費,只是為了擁有一個實體化的Bar
對象列表。 我可能會在轉換后直接鏈接我想要對列表執行的任何操作。
你的問題最困難的問題實際上不是樣板或流,而是泛型。 試圖做new B
有點亂。 你不能直接做,任何解決方法都不太干凈。
但是,對於樣板文件,由於Java 8在接口中的默認方法,您可以做得更好。 請考慮以下界面:
public interface ConversionHandler<A,B> {
B constructB(A a, Locale locale);
default List<B> convertAToB(List<A> list, Locale locale) {
return list.stream().map(a -> constructB(a, locale)).collect(Collectors.toCollection(ArrayList::new));
}
}
列表轉換樣板現在完成了,您所要做的就是在子類中實現B
構造。 但是,如果B仍然是通用的,這仍然很棘手。
public class ClassThatUsesAandB<A, B> implements ConversionHandler<A,B> {
@Override
public B constructB(A a, Locale locale) {
return null; //This is tricky
}
}
但是,如果子類是具體的,那很簡單
public class ConverterClass implements ConversionHandler<String,Integer> {
@Override
public Integer constructB(String s, Locale locale) {
return s.length();
}
}
因此,您可能希望搜索的后續操作是一種很好的設計模式,可以使通用對象的構造盡可能易於維護和讀取。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.