28

I need to convert comma separated string to list of integers. For example if I have following string

String numbersArray = "1, 2, 3, 5, 7, 9,";

Is there a way how to convert it at once to List<Integer>?

Now i see only one way to do it.

List<String> numbers = Arrays.asList(numbersArray.split(","));

And then

List<Integer> numbersInt = new ArrayList<>();
for (String number : numbers) {
    numbersInt.add(Integer.valueOf(nubmer));
}

I'm curious is there a way how to miss part with List<String> and at the first onset convert it to List<Integer>

Raedwald
  • 46,613
  • 43
  • 151
  • 237
user3127896
  • 6,323
  • 15
  • 39
  • 65

7 Answers7

48

If you're using Java 8, you can:

int[] numbers = Arrays.asList(numbersArray.split(",")).stream()
  .map(String::trim)
  .mapToInt(Integer::parseInt).toArray();

If not, I think your approach is the best option available.

Maroun
  • 94,125
  • 30
  • 188
  • 241
  • 3
    If you want to process the items “without intermediate container”, you have to use `Pattern.compile(",").splitAsStream(numbersArray) …` as otherwise, in fact, the array *is* a kind of container… – Holger Apr 22 '15 at 13:39
  • Here is my favorite. Shorter and treats different seperators and whitespace all in one go `Stream.of(numbersArray.split("\\D+")).mapToInt(Integer::parseInt).toArray();` – culmat Mar 07 '19 at 10:41
26

Using java 8 Streams:

List<Integer> longIds = Stream.of(commaSeperatedString.split(","))
                .map(Integer::parseInt)
                .collect(Collectors.toList());
Nik Kashi
  • 4,447
  • 3
  • 40
  • 63
  • 3
    The OP did ask about integers, not longs. Also, your answer is more likely to be upvoted if you add a bit more information about how and why it solves the problem (and you should also specify this only works in Java 8) – Trisha Aug 27 '15 at 11:29
  • You're using parseInt, which returns an int (not an Integer) so you're doing a conversion from a String to an int and then from an int to an Integer for the collect. If you use Integer::valueOf you will go from String to Integer. – JL_SO Aug 20 '20 at 19:23
5

I really like @MarounMaroun's answer but I wonder if it is even better to use the Arrays.stream-method instead of Arrays.asList.

int[] numbers = Arrays.stream(numbersArray.split(","))
                .map(String::trim).mapToInt(Integer::parseInt).toArray();

This SO-question discusses this further and summarizes it as such:

because you leave the conversion of the array to a stream to the JDK - let it be responsible for efficiency etc.

Community
  • 1
  • 1
wassgren
  • 18,651
  • 6
  • 63
  • 77
2

This works, as long as the String ends in a comma, like your example.

 String numbersArray = "1, 2, 3, 14, 5,";
 List<Integer> list = new ArrayList<Integer>();
 for (int i = 0, j, n = numbersArray.length(); i < n; i = j + 1) {
     j = numbersArray.indexOf(",", i);
     list.add(Integer.parseInt(numbersArray.substring(i, j).trim()));
 }

However, it's pretty useless, as on my machine it's about 2 times slower than the original.

This next solution, on the other hand, is surprisingly fast. I tested it on lists of 50000 integers obtained using Math.abs(random.nextInt()) and it was about 4 times faster than the original.

List<Integer> list = new ArrayList<Integer>();
for (int i = 0, a = 0, n = numbersArray.length(); i < n; i++) {
    char c = numbersArray.charAt(i);
    if (c == ',') {
        list.add(a);
        a = 0;
    } else if (c != ' ') {
        a = a * 10 + (c - '0');
    }
}

And this is about twice as fast again:

List<Integer> list = new ArrayList<Integer>();
for (int i = 0, a = 0, n = numbersArray.length(); i < n; i++) {
    switch(numbersArray.charAt(i)) {
        case ',': list.add(a); a = 0; break;
        case ' ': break;
        case '0': a = a * 10; break;
        case '1': a = a * 10 + 1; break;
        case '2': a = a * 10 + 2; break;
        case '3': a = a * 10 + 3; break;
        case '4': a = a * 10 + 4; break;
        case '5': a = a * 10 + 5; break;
        case '6': a = a * 10 + 6; break;
        case '7': a = a * 10 + 7; break;
        case '8': a = a * 10 + 8; break;
        case '9': a = a * 10 + 9; break;
        default: throw new AssertionError();
    }
}
Paul Boddington
  • 37,127
  • 10
  • 65
  • 116
  • Your manual parsing doesn't handle negative numbers. There's probably other edge cases where it behaves differently from `.parseInt`. While it's interesting, it's probably not a good idea to use this in production code. – Bob Dec 22 '14 at 13:25
  • 1
    I wasn't thinking of using it in production code! I was just treating this an an interesting academic exercise in writing an algorithm that's as fast as possible. You could adapt it to make it work for negatives. I don't have java 8 so I can't test those solutions, but of all the others, the `switch` one is by far the fastest one here. And apparently if you use reflection to access the `char` array backing a `String` you can double the speed of iterating over a `String`. See this question - http://stackoverflow.com/questions/8894258/fastest-way-to-iterate-over-all-the-chars-in-a-string – Paul Boddington Dec 22 '14 at 13:36
2

If you are willing to use Google Guava ( https://code.google.com/p/guava-libraries/ ) , splitter is your friend

    List<Integer> list = new ArrayList<Integer>();
    for ( String s : Splitter.on(',').trimResults().omitEmptyStrings().split("1, 2, 3, 14, 5,") ) {
      list.add(Integer.parseInt(s)); 
    }

or, you could use something similar to your original approach and:

List<Integer> list = new ArrayList<Integer>();
for (String s :"1, 2, 3, 5, 7, 9,".split(",") ) {
    list.add(Integer.parseInt(s.trim()));
}
David Soroko
  • 8,521
  • 2
  • 39
  • 51
1

If you're not on java8, then you can use Guava

Lists.transform(Arrays.asList(numbersArray.split(",")), new Function<String, Integer>() {
                    @Override
                    public Integer apply(String input) {
                        return Integer.parseInt(input.trim());
                    }
                });

As @Maroun has mentioned for Java8 you can use Streams.

int[] numbers = Arrays.asList(numbersArray.split(","))
                      .stream()
                      .map(String::trim)
                      .mapToInt(Integer::parseInt).toArray();
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Kishore Bandi
  • 5,537
  • 2
  • 31
  • 52
-1

I think below piece of code could be helpful for you.

import java.util.Scanner;

public class Solution {
    public static void main(String[] args) throws java.io.IOException {
        String numbersArray = "1, 2, 3, 5, 7, 9,";
        System.out.println(numbersArray);
        Scanner sc = new Scanner(numbersArray);
        sc.useDelimiter("(, *)*");
        try{
            while(true){
                System.out.println(sc.nextInt());
            }
        } catch (Exception e) {
            System.out.println("reading is completed");
        }
    }
}

Instead of using System.out.println add it to the Integer list.

Here we are not traversing through the complete list multiple times, instead we traverse only once and storing them in array.