创建 setter 以提供 java 列表实现 class
Create a setter to provide a java List Implementation class
我正在编写一个基于此接口的小型类型转换框架:
public interface Converter <From,To> {
public To convert(final From from);
}
这样我就可以编写自定义类型转换器,例如
public class BigDecimal2Double implements Converter<BigDecimal, Double> {
@Override
public Double convert(final BigDecimal value) {
return value != null ? value.doubleValue() : null;
}
}
以下class旨在扩展转换器的能力,以处理数据列表..
public abstract class ListConverter<From,To> implements Converter<From,To> {
public List<To> convertList(List<From> fromList){
if (fromList == null) {return null;}
List<To> toList = new ArrayList<>(); // DEFAULT IMPLEMENTATION
for(From from: fromList ){
toList.add(this.convert(from));
}
return toList;
}
public static <From,To> ListConverter<From, To> extend(final Converter<From, To> converter){
return new ListConverter<From, To>() {
@Override
public To convert(From from) {
return converter.convert(from);
}
};
}
}
因此我可以编写客户端代码,例如:
ListConverter<BigDecimal,Double> lcb2d = ListConverter.extend(new BigDecimal2Double());
List<BigDecimal> bdList = retrieveSomeBigDecList();
List<Double> convertedList = lcb2d.convertList(bdList);
如您所见,这只能为转换后的列表提供默认的 ArrayList
实现。
我想添加功能以提供与客户端代码不同的 List
实现,例如:
ListConverter<BigDecimal,Double> lcb2d = ListConverter.extend(new BigDecimal2Double());
List<BigDecimal> bdList = retrieveSomeBigDecList();
lcbd.setToListImplementation(LinkedList.class); // How to define such a method?
List<Double> convertedList = lcb2d.convertList(bdList); // would be a LinkedList
我怎样才能做到这一点?
ListConverter
class 中的以下代码无法编译:
private Class<? extends List<To>> toListImplementation = ArrayList.class;
public void setToListImplementation(Class<? extends List<To>> listImpl){
toListImplementation = listImpl;
}
另外,我应该如何使用 toListImpl
私有字段替换此行?
//... OLD
List<To> toList = new ArrayList<>(); // DEFAULT IMPLEMENTATION
//... NEW
List<To> toList = toListImplementation.newInstance(); // WOULD WORK???
编辑:Java 8 非常酷,我知道它有很多很棒的功能。
不过,我仍在研究 java 7,我想完成 java 5 合规性。
同时,问题被标记为 java-5。但如果不是,您可以添加一个版本,例如
public abstract class ListConverter<From,To> implements Converter<From,To> {
public List<To> convertList(List<From> fromList){
… // as before
}
public List<To> convertList(List<From> fromList, Supplier<List<To>> supplier){
if (fromList == null) {return null;}
List<To> toList = supplier.get();
for(From from: fromList ){
toList.add(this.convert(from));
}
return toList;
}
public static <From,To> ListConverter<From, To> extend(final Converter<From, To> converter){
return (From from) -> converter.convert(from);
}
}
这个得到一个 Supplier
,它根据请求给出一个 ArrayList。所以你可以用
来调用它
convertList(myList, LinkedList::new);
为了获得 LinkedList 而不是 ArrayList。
顺便说一句,如果你习惯了 Streams API,你就不需要这个 ListConverter。你可以只拿清单然后做
list.stream().map(converter::convert).collect(Collectors.toList())
或者,根据需要,
list.stream().map(converter::convert).collect(Collectors.toCollection(LinkedList::new))
为 class ListConverter
的用户提供一种方法来提供工厂方法来创建所需的特定种类的 List
。示例:
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
public abstract class ListConverter<From, To> implements Converter<From, To> {
private final Supplier<List<To>> listFactory;
public ListConverter(Supplier<List<To>> listFactory) {
this.listFactory = listFactory;
}
public List<To> convertList(List<From> fromList) {
if (fromList == null) {
return null;
}
List<To> toList = listFactory.get();
for (From from : fromList) {
toList.add(this.convert(from));
}
return toList;
}
public static <From, To> ListConverter<From, To> extend(Converter<From, To> converter, Supplier<List<To>> listFactory) {
return new ListConverter<From, To>(listFactory) {
@Override
public To convert(From from) {
return converter.convert(from);
}
};
}
public static <From, To> ListConverter<From, To> extend(Converter<From, To> converter) {
return extend(converter, ArrayList::new);
}
}
如果你想要一个 LinkedList
那么你可以这样做:
ListConverter<BigDecimal,Double> lcb2d =
ListConverter.extend(new BigDecimal2Double(), LinkedList::new);
edit - 对于Java5-7,可以创建一个ListFactory
接口:
import java.util.List;
public interface ListFactory<T> {
List<T> newList();
}
然后使用它,并使用匿名内部 classes 而不是 Java 8 个方法引用:
import java.util.ArrayList;
import java.util.List;
public abstract class ListConverter<From, To> implements Converter<From, To> {
private final ListFactory<To> listFactory;
public ListConverter(ListFactory<To> listFactory) {
this.listFactory = listFactory;
}
public List<To> convertList(List<From> fromList) {
if (fromList == null) {
return null;
}
List<To> toList = listFactory.newList();
for (From from : fromList) {
toList.add(this.convert(from));
}
return toList;
}
public static <From, To> ListConverter<From, To> extend(Converter<From, To> converter, ListFactory<To> listFactory) {
return new ListConverter<From, To>(listFactory) {
@Override
public To convert(From from) {
return converter.convert(from);
}
};
}
public static <From, To> ListConverter<From, To> extend(Converter<From, To> converter) {
return extend(converter, new ListFactory<To>() {
@Override
public List<To> newList() {
return new ArrayList<To>();
}
});
}
}
我正在编写一个基于此接口的小型类型转换框架:
public interface Converter <From,To> {
public To convert(final From from);
}
这样我就可以编写自定义类型转换器,例如
public class BigDecimal2Double implements Converter<BigDecimal, Double> {
@Override
public Double convert(final BigDecimal value) {
return value != null ? value.doubleValue() : null;
}
}
以下class旨在扩展转换器的能力,以处理数据列表..
public abstract class ListConverter<From,To> implements Converter<From,To> {
public List<To> convertList(List<From> fromList){
if (fromList == null) {return null;}
List<To> toList = new ArrayList<>(); // DEFAULT IMPLEMENTATION
for(From from: fromList ){
toList.add(this.convert(from));
}
return toList;
}
public static <From,To> ListConverter<From, To> extend(final Converter<From, To> converter){
return new ListConverter<From, To>() {
@Override
public To convert(From from) {
return converter.convert(from);
}
};
}
}
因此我可以编写客户端代码,例如:
ListConverter<BigDecimal,Double> lcb2d = ListConverter.extend(new BigDecimal2Double());
List<BigDecimal> bdList = retrieveSomeBigDecList();
List<Double> convertedList = lcb2d.convertList(bdList);
如您所见,这只能为转换后的列表提供默认的 ArrayList
实现。
我想添加功能以提供与客户端代码不同的 List
实现,例如:
ListConverter<BigDecimal,Double> lcb2d = ListConverter.extend(new BigDecimal2Double());
List<BigDecimal> bdList = retrieveSomeBigDecList();
lcbd.setToListImplementation(LinkedList.class); // How to define such a method?
List<Double> convertedList = lcb2d.convertList(bdList); // would be a LinkedList
我怎样才能做到这一点?
ListConverter
class 中的以下代码无法编译:
private Class<? extends List<To>> toListImplementation = ArrayList.class;
public void setToListImplementation(Class<? extends List<To>> listImpl){
toListImplementation = listImpl;
}
另外,我应该如何使用 toListImpl
私有字段替换此行?
//... OLD
List<To> toList = new ArrayList<>(); // DEFAULT IMPLEMENTATION
//... NEW
List<To> toList = toListImplementation.newInstance(); // WOULD WORK???
编辑:Java 8 非常酷,我知道它有很多很棒的功能。 不过,我仍在研究 java 7,我想完成 java 5 合规性。
同时,问题被标记为 java-5。但如果不是,您可以添加一个版本,例如
public abstract class ListConverter<From,To> implements Converter<From,To> {
public List<To> convertList(List<From> fromList){
… // as before
}
public List<To> convertList(List<From> fromList, Supplier<List<To>> supplier){
if (fromList == null) {return null;}
List<To> toList = supplier.get();
for(From from: fromList ){
toList.add(this.convert(from));
}
return toList;
}
public static <From,To> ListConverter<From, To> extend(final Converter<From, To> converter){
return (From from) -> converter.convert(from);
}
}
这个得到一个 Supplier
,它根据请求给出一个 ArrayList。所以你可以用
convertList(myList, LinkedList::new);
为了获得 LinkedList 而不是 ArrayList。
顺便说一句,如果你习惯了 Streams API,你就不需要这个 ListConverter。你可以只拿清单然后做
list.stream().map(converter::convert).collect(Collectors.toList())
或者,根据需要,
list.stream().map(converter::convert).collect(Collectors.toCollection(LinkedList::new))
为 class ListConverter
的用户提供一种方法来提供工厂方法来创建所需的特定种类的 List
。示例:
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
public abstract class ListConverter<From, To> implements Converter<From, To> {
private final Supplier<List<To>> listFactory;
public ListConverter(Supplier<List<To>> listFactory) {
this.listFactory = listFactory;
}
public List<To> convertList(List<From> fromList) {
if (fromList == null) {
return null;
}
List<To> toList = listFactory.get();
for (From from : fromList) {
toList.add(this.convert(from));
}
return toList;
}
public static <From, To> ListConverter<From, To> extend(Converter<From, To> converter, Supplier<List<To>> listFactory) {
return new ListConverter<From, To>(listFactory) {
@Override
public To convert(From from) {
return converter.convert(from);
}
};
}
public static <From, To> ListConverter<From, To> extend(Converter<From, To> converter) {
return extend(converter, ArrayList::new);
}
}
如果你想要一个 LinkedList
那么你可以这样做:
ListConverter<BigDecimal,Double> lcb2d =
ListConverter.extend(new BigDecimal2Double(), LinkedList::new);
edit - 对于Java5-7,可以创建一个ListFactory
接口:
import java.util.List;
public interface ListFactory<T> {
List<T> newList();
}
然后使用它,并使用匿名内部 classes 而不是 Java 8 个方法引用:
import java.util.ArrayList;
import java.util.List;
public abstract class ListConverter<From, To> implements Converter<From, To> {
private final ListFactory<To> listFactory;
public ListConverter(ListFactory<To> listFactory) {
this.listFactory = listFactory;
}
public List<To> convertList(List<From> fromList) {
if (fromList == null) {
return null;
}
List<To> toList = listFactory.newList();
for (From from : fromList) {
toList.add(this.convert(from));
}
return toList;
}
public static <From, To> ListConverter<From, To> extend(Converter<From, To> converter, ListFactory<To> listFactory) {
return new ListConverter<From, To>(listFactory) {
@Override
public To convert(From from) {
return converter.convert(from);
}
};
}
public static <From, To> ListConverter<From, To> extend(Converter<From, To> converter) {
return extend(converter, new ListFactory<To>() {
@Override
public List<To> newList() {
return new ArrayList<To>();
}
});
}
}