【问题标题】:How to convert a String of Integers to an ArrayList in Java?如何在 Java 中将整数字符串转换为 ArrayList?
【发布时间】:2016-01-01 09:16:48
【问题描述】:

我尝试解析一个文本文件,其中包含如下所示的行:

@KEY,_,0,1,2,_,4,5,6, ...

@KEY 只是开头的一个标识符,而以下数字是我想要存储在 ArrayList<Integer> 中的数据。

我有一个元数据类,其中包含我想在其中插入整数的数组列表:

class MetaD {
    public List<Integer> key1, key2, key3 = new ArrayList<Integer>();
}

我逐行解析文本文件;当行以@KEY 开头时,我想将元素添加到key1 列表中。如果有_,则应替换为空值:

    if(line.startsWith("@KEY")){
        metaObject.key1 = Arrays.asList(line.replace("@KEY,", "").replace("_", "").trim().split("\\s*,\\s*"));
    }

我发现这不适用于ArrayList&lt;Integer&gt;key1 必须是 ArrayList&lt;String&gt;ArrayList&lt;Object&gt; 类型才能使其工作。

有没有办法以同样的方式转换整数? 如果没有,我的想法如下:

  • 将所有内容转换为ArrayList&lt;String&gt;
  • 迭代这个新的ArrayList 的每一项并将其与Integer.parseInt() 一起转换为整数。
  • 将此新整数添加到我的ArrayList&lt;Integer&gt;

是否有更有效或更好的方式来归档我的需求?


编辑: 由于 Tunaki 在 cmets 中写道,我的想法可能是我尝试执行以下操作的唯一可能方式:

    if(line.startsWith("@KEY")){
        List<String> channelTemp =  Arrays.asList(line.replace("@KEY,", "").replace("_", "1").split("\\s*,\\s*"));
        channelTemp.forEach(item -> metaObject.channel.add(Integer.parseInt(item)));
        System.out.println("done");
    }

不幸的是,这会在第三行抛出NullPointerException,我不知道为什么。出于测试目的,我将_ 替换为1,以避免NumberFormatException。当我打印出 lambda 函数中的每个对象而不是将它们添加到我的 ArrayList&lt;Integer&gt; 时,我可以看到所有项目都有一个 Integer 值。那么为什么我会在这里得到一个异常呢?

【问题讨论】:

  • 你的想法几乎是实现它的唯一方法。如果您使用的是 Java 8,则可以使用 Stream 操作简化此操作。你应该使用Integer.valueOf,因为它会直接创建一个Integer而不涉及装箱(Integer.parseInt返回一个int而不是Integer

标签: java arraylist type-conversion


【解决方案1】:

既然你快到了,我会帮你的。

String line = "@KEY,_,0,1,2  , _,4,5,6,";
List<Integer> collect = Arrays.stream(line.replaceAll("@KEY|_", "").split(","))
        .map(String::trim)
        .filter(s -> !s.isEmpty())
        .map(Integer::valueOf).collect(Collectors.toList());
System.out.println(collect);

编辑

要获得null,您可以更改映射过程,例如:

List<Integer> collect = Arrays.stream(line.split(","))
        .skip(line.startsWith("@KEY") ? 1 : 0)
        .map(String::trim)
        .filter(s -> !s.isEmpty())
        .map(s -> "_".equals(s) ? null : Integer.valueOf(s)).collect(Collectors.toList());

【讨论】:

  • 谢谢!这会过滤掉每个空值吗?这对我来说非常糟糕,因为我想将这些数据存储在数据库中,这是我的列(其中一些值可以为 NULL)。但我认为我可以将您的答案用于我的目的,我只需将 "" 替换为 -1 或类似名称。谢谢:)
  • 后续问题:既然ArrayList允许一个元素是null,那么是否可以用Java的null替换_?像.replaceAll("_", null) 这样的东西不起作用。
  • @Drudge 这里是一个可能的管道。
  • 谢谢,您的回答很有魅力!将.replaceAll 替换为.skip 有什么原因吗?你能向我解释一下.collect(Collectors.toList()) 到底是做什么的吗?这是您的代码中唯一我不理解的部分。
  • @Drudge 因为正则表达式非常昂贵。所以不需要替换字符而是我可以说如果字符串以@KEY 开头然后跳过第一个条目。 Stream::collect 用于将流中的对象收集到特定的数据结构中,在本例中它是一个列表。
【解决方案2】:

首先,你应该用“,”分割你的字符串,然后你用 isIntegerMethod 试试你的每个字符串是否是一个整数。如果是整数,则可以将其添加到列表中。

public static void main(String[] args) throws IOException {
    String str = "@KEY,_,0,1,2,_,4,5,9";
    String [] strArr = str.split(",");
    List<Integer> intList = new ArrayList<Integer>();
    for (String string : strArr) {
        if (isInteger(string, 10)) {
            intList.add(Integer.valueOf(string));
        } else {
            System.out.println(string + " is not an integer");
        }
    }
    System.out.println(intList.toString());

}

public static boolean isInteger(String s, int radix) {
    if(s.isEmpty()) return false;
    for(int i = 0; i < s.length(); i++) {
        if(i == 0 && s.charAt(i) == '-') {
            if(s.length() == 1) return false;
            else continue;
        }
        if(Character.digit(s.charAt(i),radix) < 0) return false;
    }
    return true;
}

【讨论】:

    【解决方案3】:

    您正在尝试将整数列表放入字符串:

    metaObject.key1 = Arrays.asList(line.replace("@KEY,", "").replace("_", "").trim().split("\\s*,\\s*"));
    

    这里line.replace(...)trim() 返回Stringsplit(...) 返回String[]。 因此Arrays.asList(...) 在这里返回一个List&lt;String&gt;,这与您对key1 的定义不兼容(List&lt;Integer&gt;)。

    是的,您可以通过调用Integer.valueOf(...)Integer.parseInt(...) 将其转换为List&lt;Integer&gt;

    但我会推荐

    1. 使用 List 的新实例而不是 Arrays.asList(...),因为最新的实例将生成不可修改的集合。有时候这不是你想要的:)
    2. 使用比您自己的文本格式更具体的内容。 JSON呢?有很多库可以简化数据的解析/存储。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-26
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      • 2015-08-07
      • 2013-02-05
      相关资源
      最近更新 更多