views:

298

answers:

6

Hi.

I am doing a method that needs to return a long[]. It looks like this:

public long[] parseString(String input)

input are strings like:

  • 1, 3, 4
  • 10, 30, 40, 50

Inside parseString I use a regex to get all numbers and add them to an ArrayList as I can't know how many oconcurrences it will find.

At the end I create a long[] with the size of the arrayList and do a for each to add it to the long[] var.

Another way would be: First count every occurrence with a

while ( matcher.find() ) size++;

and then with size create a long[] of size size and do a: matcher.reset() and now save the long values in the long[] variable.

Which do you think it's the best?

Is there a better way to do this?

Remember I can't change the method signature :(

+1  A: 

You can't use toArray in this case. ArrayLists store only objects, and not primitives. Thus, you can not store int, longs, etc. You will have to either store all the objects as Long objects or create a static array of longs yourself.

monksy
+1  A: 

Because of the dichotomy between primitives and objects in Java, you can't use the generic list List<Long>.toArray(Long[]) to build a primitive array as the result. There are primitive collections which can be used, but either way - using a list or working over the groups - you're copying data from a temporary storage to a primitive array.

So either of the ways you suggest is about as good as each other. If it's performance sensitive, profile both and choose the best for your regex.

Pete Kirkham
A: 

I think you can also do something like.

public long[] parseString(String input)
{
            //1. Split with comma separated
            int nLength = input.Split(new char[] { ',' }).Length;
            long[] arList = new long[nLength];

            for (int i = 0; i < nLength; i++)
            {
                arList[i] = long.Parse(input.Split(new char[] { ',' })[i].ToString());
            }

            return arList;
}

Usage:

long[] l = parseString("10, 30, 40, 50");
KMan
This splits the string N+1 times!And what sense would there be in the split() method requiring a char[]? Yuck.I think this answerer may not be highly familiar with Java (e.g., by convention method names *always* start with a lowercase letter).
Kevin Bourrillion
-1 - overly complicated AND inefficient AND .... not even valid Java!
Stephen C
Guys, apologies if my answer disappoints you. The op asked about an idea of "Is there a better way to do this"? and not an exact code snippet. So, just to help the op understand how else he may approach the problem, I addded my two pints.@Kevin:Thanks for your feedback. The splits are N - 1 times, depending upon the number of 'comma'; the code above is guaranteed to work in C#.@Stephen: If you would go through the Eradicus's solution, it is somewhat similar. I am not sure what exactly do you mean when you say "overly complicated and inefficient".
KMan
+1  A: 
@Test
public void testParsing() throws Exception {
 String input = "1,3,5,6,33";
 long[] parsed = parseString(input);
 assertEquals(5, parsed.length);
 assertEquals(1, parsed[0]);
 assertEquals(3, parsed[1]);
 assertEquals(5, parsed[2]);
 assertEquals(6, parsed[3]);
 assertEquals(33, parsed[4]);
}
public long[] parseString(String input) {
 String[] split = input.split(Pattern.quote(","));
 long[] arr = new long[split.length];
 for (int i = 0; i < arr.length; i++) {
  arr[i] = Long.parseLong(split[i]);
 }
 return arr;
}
mhaller
+3  A: 
public long[] parseString(String input) {

        final String[] parsed = input.split(",\\s?");
        final long[] values = new long[parsed.length];

        for (int i = 0; i < parsed.length; i++) {
            values[i] = Long.parseLong(parsed[i]);
        }

        return values;
}
Joset
Sometimes the new for loop just isn't worth it. This is one of those times.
Yishai
@Yishai, why do you say so?
Joset
because you're initialising an int i which you could as easily do in a standard for-loop: for(int i = 0, n = parsed.length(); i < n; i++) { values[i] = Long.parseLong(parsed[i]); }would do the same and you'd even save one line.
Tedil
@Tedil, thanks for the info. :)
Joset
You could input.split(",\\s?") for an optional space after each comma
Peter Lawrey
@Peter Lawrey, nice! to get away with trimming.
Joset
+1  A: 

At the risk of being a huge pimp for Google's guava-libraries (I really do love it!), the Longs class makes this a one-liner:

return Longs.toArray(foundLongs);

ta-daa!

Cowan
Source code: http://code.google.com/p/guava-libraries/source/browse/trunk/src/com/google/common/primitives/Longs.java
Macarse