alexanoid
alexanoid

Reputation: 25862

Correctly convert String array to String and back in java

I have a following code:

String[] stringArray = new String[] { "One,", "Two", "Three" };
System.out.println(Arrays.toString(stringArray));

which produces the following string:

[One,, Two, Three]

Right now It is impossible to convert this string back into the same String[] with 3 elements because of two consecutive commas ,,

How to correctly make this conversion ?

UPDATED

Arrays.toString(stringArray)

is just a particular case and I'm not limited to use only this approach. I need to implement approach where conversion from String[] to String and back from String to String[] will be idempotent operation.

Upvotes: 0

Views: 6319

Answers (3)

Masoud Esmaeilian
Masoud Esmaeilian

Reputation: 72

I really don't know what you want to do, but the array separator , is in your string, so the simplest way to avoid this would be to avoid building the string with default array separator! like this:

String[] stringArray = new String[] { "One,", "Two", "Three" };
    StringBuilder string = new StringBuilder();
    string.append("[");
    for (int i = 0; i < stringArray.length; i++) {
        string.append(stringArray[i] + (i == (stringArray.length - 1) ? "" : "; "));
    }
    string.append("]");
    System.out.println(string);
    System.out.println(string.toString().substring(1, string.length() - 1).split("; "));

surely you can do some more stuff do get it work with default array separator, but it depends on what you want to do, I just choose the simplest way.

Upvotes: 0

Boris the Spider
Boris the Spider

Reputation: 61198

You state that "Arrays.toString is absolutely not required."1

I suggest you serialize the Array to Base64:

public String serializeArray(final String[] data) {
    try (final ByteArrayOutputStream boas = new ByteArrayOutputStream();
         final ObjectOutputStream oos = new ObjectOutputStream(boas)) {
        oos.writeObject(data);
        return Base64.getEncoder().encodeToString(boas.toByteArray());
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

Then deserialize the Base64 to an array:

public String[] deserializeArray(final String data) {
    try (final ByteArrayInputStream bias = new ByteArrayInputStream(Base64.getDecoder().decode(data));
         final ObjectInputStream ois = new ObjectInputStream(bias)) {
        return (String[]) ois.readObject();
    } catch (IOException | ClassNotFoundException e) {
        throw new RuntimeException(e);
    }
}

This requires Java 8.

Example:

public static void main(String args[]) throws Exception {
    String[] stringArray = new String[]{"One,", "Two", "Three"};
    String serialized = serializeArray(stringArray);
    String[] deserialized = deserializeArray(serialized);
    System.out.println(Arrays.toString(stringArray));
    System.out.println(serialized);
    System.out.println(Arrays.toString(deserialized));
}

Output

[One,, Two, Three]
rO0ABXVyABNbTGphdmEubGFuZy5TdHJpbmc7rdJW5+kde0cCAAB4cAAAAAN0AARPbmUsdAADVHdvdAAFVGhyZWU=
[One,, Two, Three]

Note, this works for any Object that implements Serializable, not just String[].


As a simple alternative, you could replace , by \, before joining the array and then also replace \, by , after splitting it. This relies on the standard "escaped delimiter" pattern that CSV uses. But it will fail if the user inputs \, somewhere in the input, so is less robust: YMMV.

public String serializeArray(final String[] data) {
    return Arrays.stream(data)
            .map(s -> s.replace(",", "\\,"))
            .collect(joining(","));
}

public String[] deserializeArray(final String data) {
    return Pattern.compile("(?<!\\\\),").splitAsStream(data)
            .map(s -> s.replace("\\,", ","))
            .toArray(String[]::new);
}

Upvotes: 4

john16384
john16384

Reputation: 8064

Convert it to a format intended for this, like JSON. Using Jackson it would be something like this:

 ObjectMapper objectMapper = new ObjectMapper();

 String out = objectMapper.writeValueAsString(Arrays.asList(array));

And back:

 List<String> strings = (List<String>) objectMapper.readValue(out, List.class);

 String[] array2 = strings.toArray();

Upvotes: 3

Related Questions