我有一个整数列表,List<Integer>
我想将所有整数对象都转换为String,从而以new结束List<String>
。
自然地,我可以创建一个新的List<String>
并遍历列表以调用String.valueOf()
每个整数,但是我想知道是否有更好的方法(阅读:更自动化)?
我有一个整数列表,List<Integer>
我想将所有整数对象都转换为String,从而以new结束List<String>
。
自然地,我可以创建一个新的List<String>
并遍历列表以调用String.valueOf()
每个整数,但是我想知道是否有更好的方法(阅读:更自动化)?
Answers:
据我所知,迭代和实例化是实现此目的的唯一方法。诸如此类的东西(对于其他潜在的帮助,因为我确定您知道该怎么做):
List<Integer> oldList = ...
/* Specify the size of the list up front to prevent resizing. */
List<String> newList = new ArrayList<>(oldList.size());
for (Integer myInt : oldList) {
newList.add(String.valueOf(myInt));
}
使用Guava-Project提供的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());
的List
返回通过transform
是一个视图背衬列表上-变换将在每个访问变换表来施加。
请注意,Functions.toStringFunction()
将其NullPointerException
应用于null时将抛出a ,因此仅在确定列表不包含null时才使用它。
Java 8.的解决方案比Guava的解决方案长一点,但是至少您不必安装库。
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());
toString
示例的时间更长,但是对于Guava的Functions库不支持的转换,它最终会更短。自定义函数仍然很容易,但是比Java 8流要多得多的代码
你在做什么是好的,但如果你觉得有必要的Java-它一起“你可以使用一个变压器和收集方法,从Apache的共享,例如:
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我会使用.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());
}
它不是Java的核心,也不是通用的,但是流行的Jakarta Commons Collections库为此类任务提供了一些有用的抽象。具体来说,看看下面的collect方法
如果您已经在项目中使用了commons集合,请考虑一下。
对于那些关心“拳击”的人们,jsight的回答是:没有。String.valueOf(Object)
在这里使用,并且int
从未执行过拆箱操作。
使用Integer.toString()
还是String.valueOf(Object)
取决于要如何处理可能的null。您是否要抛出异常(可能),或者列表中包含“空”字符串(也许)。如果是前者,是否要抛出a NullPointerException
或其他类型?
另外,jsight响应中的一个小缺陷:List
接口,您不能在其上使用new运算符。java.util.ArrayList
在这种情况下,我可能会使用a ,尤其是因为我们预先知道该列表可能会持续多长时间。
List<String> stringList = integerList.stream().map((Object s)->String.valueOf(s)).collect(Collectors.toList())
仅针对专家的答案:
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);
String
)将共享相同的后备数组(来自all
),因此实际上实际上将具有相当高的内存效率,这对于长期性能至关重要。除非您只想保留其中一个要素,否则……
Lambdaj允许以非常简单且易读的方式进行操作。例如,假设您有一个Integer列表,并且想要将它们转换为相应的String表示形式,则可以编写类似的内容;
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装箱为Integers。原则上,它可以避免从Object到Integer的贬低(因为它毫无意义,因为Object对于String.valueOf和Object.toString都足够好),但我不知道编译器是否足够聪明。从String到Object的转换应该或多或少是无操作的,因此我不希望为此担心。
我没有看到遵循空间复杂性原理的任何解决方案。如果整数列表包含大量元素,那么这将是一个大问题。
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();
}
使用流:如果说结果是整数列表(List<Integer> result
),则:
List<String> ids = (List<String>) result.stream().map(intNumber -> Integer.toString(intNumber)).collect(Collectors.toList());
解决它的方法之一。希望这可以帮助。
只是为了好玩,一个应该在JDK7中使用jsr166y fork-join框架的解决方案。
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中不太可能出现一些类型推断和语法糖,以使withMapping调用不太冗长:
.withMapping(#(Integer i) String.valueOf(i))
这是一件非常基本的事情,我不会使用外部库(这会导致您的项目中可能不需要的依赖项)。
我们有一类专门设计用于完成此类工作的静态方法。因为此代码非常简单,所以让Hotspot为我们进行优化。最近,这似乎是我的代码的主题:编写非常简单(直接)的代码,然后让Hotspot发挥作用。我们很少会遇到类似这样的代码的性能问题-当出现新的VM版本时,您将获得所有额外的速度优势等。
尽管我非常喜欢Jakarta系列,但它们不支持Generics,并使用1.4作为LCD。我对Google Collections保持警惕,因为它们被列为Alpha支持级别!
我只是想用面向对象的解决方案来解决这个问题。
如果您对域对象建模,则解决方案将在域对象中。这里的域是我们想要字符串值的整数列表。
最简单的方法是根本不转换列表。
话虽如此,为了不进行转换就将Integer的原始列表更改为Value列表,其中Value看起来像这样...
class Value {
Integer value;
public Integer getInt()
{
return value;
}
public String getString()
{
return String.valueOf(value);
}
}
与复制列表相比,这将更快并且占用更少的内存。
祝好运!