我有一个整数列表List<Integer>
,我想将所有整数对象转换为字符串,最后得到一个新的List<String>
。
当然,我可以创建一个新的List<String>
并循环遍历每个整数调用String.valueOf()
的列表,但我想知道是否有更好的(读取:更自动)这样做的方式?
答案 0 :(得分:90)
使用Google Collections from Guava-Project,您可以使用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()
在应用于null时会抛出NullPointerException
,因此只有在您确定列表不包含null时才使用它。
答案 1 :(得分:72)
据我所知,迭代和实例化是唯一的方法。类似的东西(对于其他潜在的帮助,因为我确定你知道如何做到这一点):
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));
}
答案 2 :(得分:68)
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());
答案 3 :(得分:40)
你正在做的事情很好,但如果你觉得需要'Java-it-up',你可以使用Transformer和来自collect method的Apache Commons,例如:
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);
答案 4 :(得分:9)
我没有使用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());
}
答案 5 :(得分:9)
String.valueOf的来源显示了这个:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
并不重要,但我会使用toString。
答案 6 :(得分:8)
这是一个单行解决方案,没有使用非JDK库作弊。
List<String> strings = Arrays.asList(list.toString().replaceAll("\\[(.*)\\]", "$1").split(", "));
答案 7 :(得分:5)
使用Guava和Java 8的另一个解决方案
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<String> strings = Lists.transform(numbers, number -> String.valueOf(number));
答案 8 :(得分:3)
不是核心Java,也不是通用的,但是流行的Jakarta commons集合库对于这类任务有一些有用的抽象。具体来说,看看
上的收集方法如果您已经在项目中使用了commons集合,那么需要考虑一些事项。
答案 9 :(得分:3)
在jsight的答案中,关注“拳击”的人:没有。此处使用String.valueOf(Object)
,并且不会执行int
的取消装箱。
您使用Integer.toString()
还是String.valueOf(Object)
取决于您希望如何处理可能的空值。你想抛出一个异常(可能),或者你的列表中有“null”字符串(也许)。如果是前者,你想抛出NullPointerException
还是其他类型?
此外,jsight响应中的一个小缺陷:List
是一个接口,你不能在其上使用new运算符。在这种情况下,我可能会使用java.util.ArrayList
,特别是因为我们事先知道列表可能有多长。
答案 10 :(得分:2)
@Jonathan:我可能会弄错,但我相信在这种情况下String.valueOf()将调用String.valueOf(Object)函数,而不是将其装箱到String.valueOf(int)。 String.valueOf(Object)如果为null则返回“null”,如果非null则返回Object.toString(),这不应该涉及装箱(尽管明显涉及实例化新的字符串对象)。
答案 11 :(得分:2)
我认为将Object.toString()用于调试以外的任何目的可能是一个非常糟糕的主意,即使在这种情况下这两者在功能上是等价的(假设列表没有空值)。开发人员可以自由地更改任何toString()方法的行为,而不会发出任何警告,包括标准库中任何类的toString()方法。
甚至不担心装箱/拆箱过程造成的性能问题。如果性能至关重要,只需使用数组即可。如果它真的很重要,请不要使用Java。试图超越JVM只会导致心痛。
答案 12 :(得分:2)
仅限专家的答案:
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);
答案 13 :(得分:2)
List<String> stringList = integerList.stream().map((Object s)->String.valueOf(s)).collect(Collectors.toList())
答案 14 :(得分:2)
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仅在您对结果进行迭代时才应用转换函数。
答案 15 :(得分:1)
使用原始列表中的forEach方法的更简洁的解决方案:
List<Integer> oldList = Arrays.asList(1, 2, 3, 4, 5);
List<String> newList = new ArrayList<>(oldList.size());
oldList.forEach(e -> newList.add(String.valueOf(e)));
答案 16 :(得分:1)
你无法避免“拳击开销”; Java的仿制通用容器只能存储对象,因此您的整数必须装入整数。原则上它可以避免从Object到Integer的向下转换(因为它没有意义,因为Object对String.valueOf和Object.toString都足够好),但我不知道编译器是否足够聪明。从String到Object的转换应该或多或少是一个no-op,所以我不愿意担心那个。
答案 17 :(得分:0)
这是一个基本的事情我不会使用外部库(它会在您的项目中导致您可能不需要的依赖)。
我们有一类专门用来做这些工作的静态方法。因为这个代码非常简单,所以我们让Hotspot为我们做优化。这似乎是我最近的代码中的一个主题:编写非常简单(直接)的代码,让Hotspot发挥其神奇作用。我们很少遇到像这样的代码的性能问题 - 当新的VM版本出现时,您将获得所有额外的速度优势等。
尽管我喜欢Jakarta系列,但他们不支持Generics并使用1.4作为LCD。我对Google Collections持谨慎态度,因为它们被列为Alpha支持级别!
答案 18 :(得分:0)
我没有看到任何遵循空间原则的解决方案 复杂。如果整数列表包含大量元素,那么它就是 很大的问题。
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();
}
答案 19 :(得分:0)
只是为了好玩,使用jsr166y fork-join框架的解决方案应该在JDK7中。
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))
答案 20 :(得分:0)
使用流:
如果说结果是整数列表(List<Integer> result
),则:
List<String> ids = (List<String>) result.stream().map(intNumber -> Integer.toString(intNumber)).collect(Collectors.toList());
解决问题的方法之一。希望这会有所帮助。
答案 21 :(得分:-1)
我只是想用一个面向对象的解决方案来解决这个问题。
如果您对域对象建模,则解决方案位于域对象中。这里的域是我们想要字符串值的整数列表。
最简单的方法是根本不转换列表。
话虽这么说,为了在不转换的情况下进行转换,将原始的Integer列表更改为List of Value,其中Value看起来像这样......
class Value {
Integer value;
public Integer getInt()
{
return value;
}
public String getString()
{
return String.valueOf(value);
}
}
这比复制List更快,占用更少的内存。
祝你好运!