user3127896
user3127896

Reputation: 6573

convert comma separated string to list without intermediate container

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>

Upvotes: 29

Views: 68980

Answers (7)

Kishore Bandi
Kishore Bandi

Reputation: 5721

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

Upvotes: 1

Maroun
Maroun

Reputation: 95978

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.

Upvotes: 48

Nik Kashi
Nik Kashi

Reputation: 4606

Using java 8 Streams:

List<Integer> longIds = Stream.of(commaSeperatedString.split(","))
                .map(Integer::parseInt)
                .collect(Collectors.toList());

Upvotes: 26

Paul Boddington
Paul Boddington

Reputation: 37655

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

Upvotes: 2

wassgren
wassgren

Reputation: 19221

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.

Upvotes: 5

santosh Kumar
santosh Kumar

Reputation: 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.

Upvotes: -1

David Soroko
David Soroko

Reputation: 9096

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

Upvotes: 2

Related Questions