将List <Integer>转换为List <String>
我有一个整数List<Integer>
, List<Integer>
,我想将所有的整数对象转换为string,从而完成一个新的List<String>
。
当然,我可以创build一个新的List<String>
并遍历每个整数调用String.valueOf()
的列表,但我想知道是否有一个更好的(读: 更自动 )的方式吗?
据我所知,迭代和实例化是唯一的方法来做到这一点。 像(对于其他潜在的帮助,因为我相信你知道如何做到这一点):
List<Integer> oldList = ... /* Specify the size of the list up front to prevent resizing. */ List<String> newList = new ArrayList<String>(oldList.size()) for (Integer myInt : oldList) { newList.add(String.valueOf(myInt)); }
使用Google Collections ,您可以使用Lists类中的transform
方法
import com.google.common.collect.Lists; import com.google.common.base.Functions List<Integer> integers = Arrays.asList(1, 2, 3, 4); List<String> strings = Lists.transform(integers, Functions.toStringFunction());
transform
返回的List
是一个支持列表视图 – 转换将应用于每个访问转换列表。
请注意, Functions.toStringFunction()
将应用于null时抛出NullPointerException
,所以只有在确定列表不包含null的情况下才使用它。
Java 8的解决scheme比Guava稍长一些,但至less不需要安装一个库。
import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; //... List<Integer> integers = Arrays.asList(1, 2, 3, 4); List<String> strings = integers.stream().map(Object::toString) .collect(Collectors.toList());
你正在做的是好的,但是如果你觉得需要“Java-up-up”,你可以使用Transformer和Apache Commons的collect方法 ,例如:
public class IntegerToStringTransformer implements Transformer<Integer, String> { public String transform(final Integer i) { return (i == null ? null : i.toString()); } }
..接着..
CollectionUtils.collect( collectionOfIntegers, new IntegerToStringTransformer(), newCollectionOfStrings);
String.valueOf的来源显示了这个:
public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); }
不是那么重要,但我会用toString。
而不是使用String.valueOf我会使用.toString(); 它避免了@ johnathan.holland描述的一些自动装箱
javadoc说valueOf返回与Integer.toString()相同的东西。
List<Integer> oldList = ... List<String> newList = new ArrayList<String>(oldList.size()); for (Integer myInt : oldList) { newList.add(myInt.toString()); }
这是一个非线程解决scheme,不会与非JDK库作弊。
List<String> strings = Arrays.asList(list.toString().replaceAll("\\[(.*)\\]", "$1").split(", "));
另一个使用Guava和Java 8的解决scheme
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); List<String> strings = Lists.transform(numbers, number -> String.valueOf(number));
不是核心Java,也不是通用的,但stream行的雅加达公共collections库对这类任务有一些有用的抽象。 具体来说,看看收集的方法
CollectionUtils
有些事情要考虑,如果你已经在你的项目中使用公共collections。
对于jsight回答中关心“拳击”的人来说,没有一个。 在这里使用String.valueOf(Object)
,并且不进行拆箱到int
。
无论您使用Integer.toString()
或String.valueOf(Object)
取决于您想如何处理可能的空值。 你想抛出一个exception(可能),或者在你的列表(也许)有“空”string。 如果前者,你想抛出一个NullPointerException
或其他types?
另外,jsight的回应中有一个小缺陷: List
是一个接口,你不能在其上使用新的操作符。 在这种情况下,我可能会使用java.util.ArrayList
,特别是因为我们知道列表可能会有多长。
@Jonathan:我可能会误解,但我相信在这种情况下String.valueOf()将调用String.valueOf(Object)函数,而不是装箱到String.valueOf(int)。 String.valueOf(Object)如果为null,则返回“null”;如果非null,则不返回Box(尽pipe显然实例化了新的string对象),则返回Object.toString()。
我认为使用Object.toString()用于debugging以外的任何目的可能是一个非常糟糕的主意,即使在这种情况下,两者在function上是等同的(假设列表没有空值)。 开发人员可以自由地更改任何toString()方法的行为,而不会有任何警告,包括标准库中任何类的toString()方法。
不要担心由装箱/拆箱过程造成的性能问题。 如果性能非常关键,只需使用一个数组。 如果真的很关键,不要使用Java。 试图超越JVM只会导致心痛。
只有专家的答案:
List<Integer> ints = ...; String all = new ArrayList<Integer>(ints).toString(); String[] split = all.substring(1, all.length()-1).split(", "); List<String> strs = Arrays.asList(split);
Lambdaj允许以非常简单和可读的方式执行此操作。 例如,假设你有一个Integer的列表,并且你想把它们转换成相应的string表示forms,你可以这样写;
List<Integer> ints = asList(1, 2, 3, 4); Iterator<String> stringIterator = convertIterator(ints, new Converter<Integer, String> { public String convert(Integer i) { return Integer.toString(i); } }
只有在迭代结果时,Lambdaj才会应用转换函数。
你无法避免“拳击开销”; Java的虚拟通用容器只能存储对象,所以你的int必须被装箱到整数。 原则上,它可以避免从Object转换为Integer(因为它没有意义,因为Object对于String.valueOf和Object.toString来说足够好),但是我不知道编译器是否足够聪明。 从String到Object的转换应该或多或less是没有操作的,所以我不愿担心那个。
只是为了好玩,一个使用JDK7中的jsr166y fork-join框架的解决scheme。
import java.util.concurrent.forkjoin.*; private final ForkJoinExecutor executor = new ForkJoinPool(); ... List<Integer> ints = ...; List<String> strs = ParallelArray.create(ints.size(), Integer.class, executor) .withMapping(new Ops.Op<Integer,String>() { public String op(Integer i) { return String.valueOf(i); }}) .all() .asList();
(免责声明:未编译,规范未定稿等)
不太可能在JDK7中是一个types推理和语法糖,使与映射调用较less冗长:
.withMapping(#(Integer i) String.valueOf(i))
这是一个基本的东西,我不会使用外部库(这将导致您的项目,您可能不需要依赖项)。
我们有一类静态方法专门为做这些工作。 因为这个代码很简单,我们让Hotspot为我们做优化。 这似乎是最近我的代码中的一个主题:编写非常简单(直接)的代码,让Hotspot发挥它的魔力。 我们很less遇到像这样的代码的性能问题 – 当一个新的VM版本出现时,您可以获得所有额外的速度优势等等。
尽pipe我喜欢雅加达collections,但他们不支持generics,并使用1.4作为LCD。 我对Googlecollections夹感到警惕,因为它们被列为Alpha支持级别!
我没有看到任何解决空间复杂性问题的解决scheme。 如果整数列表中有大量的元素,那么这是个大问题。
It will be really good to remove the integer from the List<Integer> and free the space, once it's added to List<String>.
我们可以使用迭代器来实现相同的。
List<Integer> oldList = new ArrayList<>(); oldList.add(12); oldList.add(14); ....... ....... List<String> newList = new ArrayList<String>(oldList.size()); Iterator<Integer> itr = oldList.iterator(); while(itr.hasNext()){ newList.add(itr.next().toString()); itr.remove(); }
我只是想用面向对象的解决scheme来解决这个问题。
如果您为域对象build模,则该解决scheme位于域对象中。 这里的域是我们想要的string值的整数列表。
最简单的方法是根本不转换列表。
也就是说,为了转换而不转换,将整数的原始列表更改为值列表,其中值看起来像这样…
class Value { Integer value; public Integer getInt() { return value; } public String getString() { return String.valueOf(value); } }
这会比复制列表更快,占用更less的内存。
祝你好运!