代码之家  ›  专栏  ›  技术社区  ›  Yann Ramin

将列表<整数>转换为列表<字符串>

  •  119
  • Yann Ramin  · 技术社区  · 16 年前

    我有一个整数列表, List<Integer> 我想将所有整数对象转换为字符串,从而得到一个新的 List<String> .

    当然,我可以创造一个新的 列表<字符串> 并循环调用列表 String.valueOf() 对于每个整数,我想知道是否有更好的(读: 更自动化 )如何做到这一点?

    22 回复  |  直到 7 年前
        1
  •  72
  •   erickson    16 年前

    使用 Google Collections from Guava-Project ,你可以使用 transform 方法在 Lists

    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 返回由 使改变 是a 看法 在后备列表上-转换将应用于对转换列表的每次访问。

    请注意 Functions.toStringFunction() 会扔一个 NullPointerException 当应用于null时,只有当你确定你的列表中不会包含null时,才使用它。

        2
  •  87
  •   milchreis Romain Hippeau    7 年前

    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());
    

    对于Java 11,

    List<String> strings = integers.stream().map(Object::toString)
                                            .collect(Collectors.toUnmodifiableList());
    

    还是没有 map 方便的方法,真的吗?

        3
  •  65
  •   Hakanai    11 年前

    据我所知,迭代和实例化是唯一的方法。类似(对于其他潜在的帮助,因为我相信你知道如何做到这一点):

    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)); 
    }
    
        4
  •  40
  •   Dmitry Ginzburg    10 年前

    你所做的一切都很好,但如果你觉得有必要“Java化”,你可以使用 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);
    
        5
  •  9
  •   Mike Polen    16 年前

    String.valueOf的源代码显示如下:

    public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }
    

    这并不重要,但我会用toString。

        6
  •  9
  •   ScArcher2    16 年前

    我使用.toString()代替String.valueOf;它避免了@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()); 
    }
    
        7
  •  8
  •   Garrett Hall    14 年前

    这是一个不欺骗非JDK库的单行解决方案。

    List<String> strings = Arrays.asList(list.toString().replaceAll("\\[(.*)\\]", "$1").split(", "));
    
        8
  •  5
  •   sandrozbinden    11 年前

    使用Guava和Java 8的另一种解决方案

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    List<String> strings = Lists.transform(numbers, number -> String.valueOf(number));
    
        9
  •  3
  •   serg10    16 年前

    对于关注“拳击”的人,jsight的回答是:没有。 String.valueOf(Object) 此处使用,无需拆箱 int 曾经被执行过。

    您是否使用 Integer.toString() String.valueOf(对象) 这取决于您希望如何处理可能的空值。您想抛出异常(可能),还是在列表中有“null”字符串(可能)。如果是前者,你想扔 NullPointerException 还是其他类型?

    此外,jsight的响应中存在一个小缺陷: List 是一个接口,你不能在上面使用新运算符。我可能会使用 java.util.ArrayList 在这种情况下,尤其是因为我们预先知道列表可能有多长。

        10
  •  3
  •   erickson    16 年前
    List<String> stringList = integerList.stream().map((Object s)->String.valueOf(s)).collect(Collectors.toList())
    
        11
  •  2
  •   jsight TaherT    16 年前

    不是核心Java,也不是泛型的,但流行的Jakarta commons集合库对这类任务有一些有用的抽象。具体来说,请查看上的收集方法

    CollectionUtils

    如果你已经在项目中使用了公共集合,那么需要考虑一些事情。

        12
  •  2
  •   Tim Frey    16 年前

    使用原始列表中的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)));
    
        13
  •  2
  •   Tom Hawtin - tackline    16 年前

    @Jonathan:我可能错了,但我相信在这种情况下,String.valueOf()将调用String.valueOf函数,而不是被装箱为String.valueOf。如果String.valueOf(Object)为null,则只返回“null”,如果非null,则调用Object.toString(),这不应该涉及装箱(尽管显然涉及实例化新的字符串对象)。

        14
  •  2
  •   Mario Fusco    15 年前

    我认为将Object.toString()用于调试以外的任何目的可能是一个非常糟糕的主意,即使在这种情况下,两者在功能上是等效的(假设列表中没有空值)。开发人员可以在没有任何警告的情况下自由更改任何toString()方法的行为,包括标准库中任何类的toString(()方法。

    甚至不用担心装箱/拆箱过程造成的性能问题。如果性能至关重要,只需使用数组。如果真的很重要,不要使用Java。试图超越JVM只会让人心痛。

        15
  •  1
  •   DrPizza    16 年前

    仅供专家回答:

        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);
    
        16
  •  0
  •   Tom Hawtin - tackline    16 年前

    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仅在迭代结果时应用转换函数。

        17
  •  0
  •   John Wright    16 年前

    你无法避免“拳击开销”;Java的伪泛型容器只能存储对象,所以你的整数必须被打包成整数。原则上,它可以避免从Object向下转换为Integer(因为这毫无意义,因为Object对于String.valueOf和Object.toString都足够好),但我不知道编译器是否足够聪明。从String到Object的转换应该或多或少是不可行的,所以我不想担心这个问题。

        18
  •  0
  •   nagendra547    7 年前

    只是为了好玩,一个使用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中不太可能有一些类型推理和语法糖,使Mapping调用不那么冗长:

        .withMapping(#(Integer i) String.valueOf(i))
    
        19
  •  -1
  •   athspk RNJ    12 年前

    这是一件非常基本的事情,我不会使用外部库(它会在你的项目中产生你可能不需要的依赖关系)。

    我们有一类专门为完成这类工作而设计的静态方法。因为这段代码非常简单,我们让Hotspot为我们做优化。这似乎是我最近代码中的一个主题:编写非常简单(直接)的代码,让Hotspot发挥它的魔力。我们很少遇到这样的代码性能问题——当新的VM版本出现时,你会得到所有额外的速度优势等。

    尽管我很喜欢Jakarta系列,但它们不支持Generics,而是使用1.4作为LCD。我对谷歌收藏持谨慎态度,因为它们被列为Alpha支持级别!