我想创建一个非常通用的实用程序方法,以获取任何Collection并将其转换为用户可选类的Collection,该类从Number扩展(Long,Double,Float,Integer等)
我想到了使用Google集合来转换集合并返回不可变列表的代码。
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); }
可以这样使用:
// Convert List<String> to List<Long> List<Long> ids = MiscUtils.toNumberList(productIds, Long.class);
是我的代码过度杀伤力,还是您将如何简化它,同时又使其足够通用?
我认为这段代码最重要的方面是Function方法本身。我也认为切换Function主体中允许的子类没有任何意义,因为您已经知道Number要在Function创建子类时返回哪种类型的子类。如果给出的话,您的方法也会失败,这也是一个小问题BigInteger.class。
Function
Number
BigInteger.class
鉴于此,我要做的是创建一个实用工具类(我们称之为它Numbers),并在其上提供方法,使每个方法返回一个Function(可以是enum单例)将a解析String为特定类型的方法Number。那是:
Numbers
enum
String
public class Numbers { public static Function<String, Integer> parseIntegerFunction() { ... } public static Function<String, Long> parseLongFunction() { ... } ... }
它们每个都可以这样实现:
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"; } }
然后可以使用此功能,但用户需要:
List<String> strings = ... List<Integer> integers = Lists.transform(strings, Numbers.parseIntegerFunction());
与您的方法相比,此方法有很多优点:
ImmutableList
BigInteger
附带说明一下,我建议将返回ImmutableListbe ImmutableList而不是List… 的任何方法的返回类型设为…,它提供对该方法的客户有用的信息。
List
编辑:
如果您 确实需要 更多动态的东西(即,您希望具有某些实例的类Class<T extends Number>能够将Strings转换为该Number类型),则还可以添加如下查找方法:
Class<T extends 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 }
但是,如果有一个Number子类没有提供,则它与原始方法有同样的问题Function。似乎在很多情况下这都没有用。