基本思想是我有一個將資料轉換為不同資料的介面,我想使用這個介面來轉換特定的資料子集。
public static interface Data<D> {
// transform the data into different data
<T> Data<T> transform(Function<D,T> transformer);
}
// "Something" that has been labeled
public static interface Labeled {
String getLabel();
}
// class intended to use the Data<D> interface to transform labeled data specifically
public static class LabeledData<L extends Labeled> implements Data<L> {
public final L labeledData;
public LabeledData(L labeledData) {
this.labeledData= labeledData;
}
// of course this will not compile because it does not override
// <T> Data<T> transform(Function<D,T> transformer);
@Override
public <T extends Labeled> LabeledData<T> transform(Function<L,T> transformer) {
return new LabeledData<>(transformer.apply(labeledData));
}
}
無論如何要重新宣告 Data.transform 或重新排列 LabeledData 以完成所需的功能和流程?
我知道我“可以”創建 LabeledData.transformLabled(...) 并定義原始轉換以某種方式轉換為 LabledData 或拋出例外,但這聽起來不是一個很好的解決方案。
我也可以傳入一個 T LabeledData<L extends Labeled, T extends Labeled>
,但我認為這會將一次使用限制為一種轉換型別,除非有一些創造性的方法可以做到這一點。
uj5u.com熱心網友回復:
您可以將額外的型別引數添加到Data
:
public interface Data<TData, TBound> {
<TTarget extends TBound> Data<TTarget, TBound> transform(Function<TData, TTarget> transformer);
}
TBound
用作方法型別引數的界限,TTarget
.
現在標簽資料類'transform
將覆寫介面方法:
public static class LabeledData<TLabel extends Labeled> implements Data<TLabel, Labeled> {
public final TLabel labeledData;
public LabeledData(TLabel labeledData) {
this.labeledData= labeledData;
}
@Override
public <TTarget extends Labeled> LabeledData<TTarget> transform(Function<TLabel, TTarget> transformer) {
return new LabeledData<>(transformer.apply(labeledData));
}
}
請注意,如果串列中有一堆Data
不同TBound
型別的,則不能使用例如map
:
// assume that data1, data2, data3 all have different TBounds
List<Data<String, ?>> list = List.of(data1, data2, data3);
list.stream.map(x -> x.transform(y -> f(y))).toList();
無論f(y)
回傳什么,這都不是型別安全的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/522323.html
標籤:爪哇仿制药界面函数式编程