我在Java中有以下方法:
public <T> List<?> getList(String str, Class<T> clazz ){
List<T> lst = new ArrayList<>();
String[] arr = str.split(",");
for(String s : arr){
lst.add(clazz.cast(s));
}
return lst;
}
我想要这个方法的输出是这样的:
List<Integer> lst = getList("1,2",Integer.class)
List<String> lst = getList("ab,cfv",String.class)
...
...
etc
但是这里的问题是,当我通过“
1,2
”和Integer.class
时,我在“classCastException
”处得到clazz.cast(s)
我在这里做错了什么?
您的问题与您尝试将
String
转换为 Integer
的事实有关,因为 String
不是 Integer
的子类,您应该提供一个 Function
,它将将您的 String
转换为目标类型,如下所示:
public <T> List<T> getList(String str, Function<String, T> parser){
return Arrays.stream(str.split(",")).map(parser).collect(Collectors.toList());
}
示例:
List<Integer> lst = getList("1,2", Integer::valueOf);
System.out.println(lst);
输出:
[1, 2]
之前的代码适用于 Java 8 及以上版本,对于以前的版本,逻辑是相同的,您只需使用 Google Guava
中的
FluentIterable
替换 Stream
并使用 com.google.common.base.Function
而不是 java.util.function.Function
结果如下:
public <T> List<T> getList(String str, Function<String, T> parser){
return FluentIterable.from(Arrays.asList(str.split(","))).transform(parser).toList();
}
示例:
List<Integer> lst = getList(
"1,2",
new Function<String, Integer>() {
public Integer apply(final String input) {
return Integer.valueOf(input);
}
}
);
输出:
[1, 2]
整数和字符串不在同一层次结构中。它们都源自对象,但分支方式不同。您可以按照其他答案所述进行操作,或者将参数 String 更改为 Object。
Object
/ \
/ \
String Integer
另一种方法是创建
ICaster
界面:
public interface ICaster<T> {
T cast(String a);
}
及其实现,例如:
public class IntegerCaster implements ICaster<Integer> {
@Override
public Integer cast(String a) {
return Integer.parseInt(a);
}
}
那么,您应该使用
Class<T> clazz
,而不是 getList
方法中的 ICaster<T> caster
参数。
这是新的
getList
方法:
public static <T> List<?> getList(String str, ICaster<T> caster){
List<T> lst = new ArrayList<>();
String[] arr = str.split(",");
for(String s : arr){
lst.add(caster.cast(s));
}
return lst;
}
和用法示例:
List<Integer> lst = (List<Integer>) getList("1,2",new IntegerCaster());
输出应该是:
[1, 2]