【问题标题】:Elegant way to convert a String[] to an int[] (or an ArrayList<String> to ArrayList<Integer>)将 String[] 转换为 int[](或 ArrayList<String> 转换为 ArrayList<Integer>)的优雅方式
【发布时间】:2016-03-17 07:54:54
【问题描述】:

我正在构建一个 Android 应用程序,在该应用程序中我收到一条由逗号分隔的数字消息。示例输入是:

1,2,3,4,1,2,31,12,13,16

我收到这个并将其分配为字符串,然后使用 split 方法创建一个字符串[]:

String input = "1,2,3,4,1,2,31,12,13,16";
String[] arrayInput = input.split(",");

现在我有了输入的数组版本。接下来我要做的是将其转换为int[],主要用于优雅的编码。

现在,我实在受不了了:

int[] aGroup = Arrays.copyOfRange(arrayInput, 0, 3);

因为我会得到类型不匹配。为了聪明,我尝试了:

int[] aGroup = Integer.valueOf(Arrays.copyOfRange(arrayInput, 0 ,3));

Integer.valueOf() 需要一个字符串输入,而不是多个数组元素。

我知道我可以像这样使用一个花哨的 for-each 循环:

List<Integer> arrayInputInt = new ArrayList<Integer>();
for(String entry : arrayInput){
    arrayInputInt.add(Integer.valueOf(entry));
}

或类似的东西。虽然这个 for-each 循环看起来干净优雅,但我想知道是否有一个更优雅、更赏心悦目,一个线性 String[] 到 int[] 转换器。

编辑

This question 已链接,因为我的问题可能与此问题重复。问题中的答案使用循环遍历String ArrayList 中的每个元素,尝试解析它们,然后将其转换为Integer 并将其放入Integer ArrayList 中。我正在寻找的解决方案是使用 String[] 到 int[] 转换的单行无循环类型。

【问题讨论】:

  • 你可以使用 RxJava map
  • 我不这么认为,因为我还没有更新我的 Java。
  • 我跳过了你使用的是 Android,所以你需要下载 RxJava 库才能使用 Streams
  • 我在这里没有看到任何与 android 相关的内容
  • @greenapps 可能。正如“cricket_007”在我的回答中指出的那样,“这是一个 Android 应用程序。本身不支持 lambda”。

标签: java android arrays string arraylist


【解决方案1】:

在 lambda 之前,我通过创建转换器接口和 convertList 实用方法来解决这个问题

 interface Converter<S,T>{ 
        T convert(S source); 
 }



  class ListConverter{ 
       static public <S,T> List<T> convertList(List<S> source,Converter<S,T> converter){ 
         List<T> target= new ArrayList<>();
         for (S s : source){ 
            target.add(converter(s)); 
         }
         return target; 
       }
   }

如果你想使用它,你可以这样做

List<Integer> ints = ListConverter.convertList(Arrays.asList(input.split(","),new Converter<String,Integer>(){
public Integer convert(String source){
return Integer.parseInt(source);

}
})

显然你不需要每次都需要实例化转换器,你可以为常用转换器创建单例

【讨论】:

    【解决方案2】:
    String str = "[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]";
    int[] arr = Arrays.stream(str.substring(1, str.length()-1).split(",")).map(String::trim).mapToInt(Integer::parseInt).toArray();
    System.out.println(Arrays.toString(arr));
    

    【讨论】:

    • Android 没有 Java 8 功能
    • Android 似乎没有 Arrays.stream() 方法。
    • 你必须把你的java变成java 8,它也可以在android上运行。
    • @Amit 正如我想说的,Android 无法编译和运行 Java 8。
    • 不仅它还没有java 8的功能(可以添加),Android也没有java 8的功能,比如Arrays.stream
    【解决方案3】:

    您是否希望像这样使用 lambda 表达式? (这需要导入RxJava

    // List<String> s = new ArrayList<String>();
    // s.add("1");
    // s.add("2");               // ["1","2"]
    List<Integer> list = new ArrayList<Integer>(); 
    s.forEach((val) -> list.add(Integer.valueOf(val)));   // or parseInt
    // System.out.println(list); // [1,2]
    

    【讨论】:

    • 这是一款安卓应用。本身不支持 lambda
    • 我明白了。 @cricket_007 RxJava 库没有帮助吗?
    • 他们会的,但我认为如果你想使用 lambdas,retrolambda 也需要包括在内
    • @cricket_007 对于这样的事情,可能只是很多导入库,不是吗?还是你觉得值得?
    • 对于这么简单的事情,不,但我见过包含数十个库的项目,所以只要它们提供一些功能,就值得。这就是代码优雅的代价。
    【解决方案4】:
    String line = scanner.nextLine();
    String[] numberStrs = line.split(",");
    int[] numbers = new int[numberStrs.length];
    
    for(int i = 0;i < numberStrs.length;i++) {
        /*
         * Note that this is assuming valid input
         * If you want to check then add a try/catch 
         * and another index for the numbers if to continue adding the others
         */
        numbers[i] = Integer.parseInt(numberStrs[i]);
    }
    

    【讨论】:

    • 很好的尝试回答,但问题是已经写了比你回答的更好的方法。您需要提供更多更好的选择,然后在代码中使用。可能是一个班轮......
    【解决方案5】:

    使用retrolambdaa little library for functional things

    List<Integer> res = FuncIter
        .iter(input.split(","))
        .map(Integer::valueOf)
        .collect();
    

    注意:retrolambda 为您提供来自 java 8 的函数引用和 lambda。FuncIter 库是一个非常简单的高阶函数集合,例如 map

    【讨论】:

      猜你喜欢
      • 2021-02-21
      • 1970-01-01
      • 2014-05-16
      • 2011-08-20
      • 1970-01-01
      • 2011-12-04
      • 1970-01-01
      • 1970-01-01
      • 2017-11-09
      相关资源
      最近更新 更多