Eli*_*oto 10 java generics collections guava
我想创建一个非常通用的实用程序方法来获取任何Collection并将其转换为从Number(Long,Double,Float,Integer等)扩展的用户可选类的集合.
我想出了这个代码,它使用Google Collections来转换Collection并返回一个Immutable List.
import java.util.List;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
/**
* Takes a {@code List<String>} and transforms it into a list of the
* specified {@code clazz}.
*
* @param <T>
* @param stringValues
* the list of Strings to be used to create the list of the
* specified type
* @param clazz
* must be a subclass of Number. Defines the type of the new List
* @return
*/
public static <T extends Number> List<T> toNumberList(List<String> stringValues, final Class<T> clazz) {
List<T> ids = Lists.transform(stringValues, new Function<String, T>() {
@SuppressWarnings("unchecked")
@Override
public T apply(String from) {
T retVal = null;
if (clazz.equals(Integer.class)) {
retVal = (T) Integer.valueOf(from);
} else if (clazz.equals(Long.class)) {
retVal = (T) Long.valueOf(from);
} else if (clazz.equals(Float.class)) {
retVal = (T) Float.valueOf(from);
} else if (clazz.equals(Double.class)) {
retVal = (T) Double.valueOf(from);
} else {
throw new RuntimeException(String.format("Type %s is not supported (yet)", clazz.getName()));
}
return retVal;
}
});
return ImmutableList.copyOf(ids);
}
Run Code Online (Sandbox Code Playgroud)
它可以像这样使用:
// Convert List<String> to List<Long>
List<Long> ids = MiscUtils.toNumberList(productIds, Long.class);
Run Code Online (Sandbox Code Playgroud)
我的代码是否过度杀伤,或者您如何简化它并同时保持足够的通用性?
我认为这个代码最重要的方面是Function方法本身.我也不认为切换Function正文中允许的子类是有意义的,因为您已经知道Number在Function创建时要返回的类型.如果给出的话,你的方法也会失败,这也有点问题BigInteger.class.
鉴于此,我要做的是创建一个实用程序类(让我们调用它Numbers)并在其上提供方法,每个方法返回一个Function(可以是一个enum单例)来解析String一个特定类型的Number.那是:
public class Numbers {
public static Function<String, Integer> parseIntegerFunction() { ... }
public static Function<String, Long> parseLongFunction() { ... }
...
}
Run Code Online (Sandbox Code Playgroud)
他们每个都可以这样实现:
public static Function<String, Integer> parseIntegerFunction() {
return ParseIntegerFunction.INSTANCE;
}
private enum ParseIntegerFunction implements Function<String, Integer> {
INSTANCE;
public Integer apply(String input) {
return Integer.valueOf(input);
}
@Override public String toString() {
return "ParseIntegerFunction";
}
}
Run Code Online (Sandbox Code Playgroud)
然后可以使用它,但用户需要:
List<String> strings = ...
List<Integer> integers = Lists.transform(strings, Numbers.parseIntegerFunction());
Run Code Online (Sandbox Code Playgroud)
这种方法比你的方法有很多优点:
Function...我们知道我们正在创建什么类型的数字并且只是这样做.快点.Function可以在任何地方使用...用户不会像你的方法那样被迫使用它(将转换后的值复制到一个ImmutableList.Function您想要允许的s.如果没有BigInteger解析函数,用户就不能调用它,而不是在编译时完全合法,然后在运行时失败,就像在你的例子中一样.作为旁注,我建议使用返回ImmutableListbe 的任何方法的返回类型ImmutableList而不是List...它提供对方法的客户端有用的信息.
编辑:
如果你真的需要更动态的东西(即你想要一些实例的类Class<T extends Number>能够将Strings转换为该Number类型),你还可以添加一个查找方法,如:
public static <T extends Number> Function<String, T> parseFunctionFor(Class<T> type) {
// lookup the function for the type in an ImmutableMap and return it
}
Run Code Online (Sandbox Code Playgroud)
这与原始方法存在相同的问题,但是,如果存在Number未提供Functionfor 的子类.它似乎也不会有很多情况会有用.
| 归档时间: |
|
| 查看次数: |
11510 次 |
| 最近记录: |