Convert array string to string and vice versa in Java

I have a String [] array in Java and must first encode / convert it to String, and then hide it back into the String [] array in code. The thing is, I can have any character in a string in the String [] array, so I have to be very careful when coding. And all the information necessary for its decoding should be on the last line. I cannot return a string and some other information to an additional variable.

My algorithm that I have developed so far is as follows:

  • Add all lines next to each other, for example: String [] a = {"lala", "exe", "a"} in String b = "lalaexea"

  • Add at the end of the string the lengths of all the lines from String [], separated from the main text by the $ symbol, and then each length, separated by a comma, like this:

b = "lalaexea $ 4.3.1"

Then, when it was converted back, I would first read the lengths at the back, and then based on them, the real lines.

But maybe there is an easier way?

Hooray!

+7
source share
4 answers

If you don't want to spend so much time on string operations, you can use Java serialization + common codecs as follows:

public void stringArrayTest() throws IOException, ClassNotFoundException, DecoderException { String[] strs = new String[] {"test 1", "test 2", "test 3"}; System.out.println(Arrays.toString(strs)); // serialize ByteArrayOutputStream out = new ByteArrayOutputStream(); new ObjectOutputStream(out).writeObject(strs); // your string String yourString = new String(Hex.encodeHex(out.toByteArray())); System.out.println(yourString); // deserialize ByteArrayInputStream in = new ByteArrayInputStream(Hex.decodeHex(yourString.toCharArray())); System.out.println(Arrays.toString((String[]) new ObjectInputStream(in).readObject())); } 

This will return the following output:

 [test 1, test 2, test 3] aced0005757200135b4c6a6176612e6c616e672e537472696e673badd256e7e91d7b47020000787000000003740006746573742031740006746573742032740006746573742033 [test 1, test 2, test 3] 

If you are using maven, you can use the following dependency for the commons codec:

 <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.2</version> </dependency> 

As stated in base64 (changing two lines):

 String yourString = new String(Base64.encodeBase64(out.toByteArray())); ByteArrayInputStream in = new ByteArrayInputStream(Base64.decodeBase64(yourString.getBytes())); 

In the case of Base64, the final line is shorter for the code below:

 [test 1, test 2, test 3] rO0ABXVyABNbTGphdmEubGFuZy5TdHJpbmc7rdJW5+kde0cCAAB4cAAAAAN0AAZ0ZXN0IDF0AAZ0ZXN0IDJ0AAZ0ZXN0IDM= [test 1, test 2, test 3] 

As for the time for each approach, I perform 10 ^ 5 executions of each method, and the result was as follows:

  • Line Processing: 156 ms
  • Hex: 376 ms
  • Base64: 379 ms

Code used for the test:

 import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.util.StringTokenizer; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; public class StringArrayRepresentationTest { public static void main(String[] args) throws IOException, ClassNotFoundException, DecoderException { String[] strs = new String[] {"test 1", "test 2", "test 3"}; long t = System.currentTimeMillis(); for (int i =0; i < 100000;i++) { stringManipulation(strs); } System.out.println("String manipulation: " + (System.currentTimeMillis() - t)); t = System.currentTimeMillis(); for (int i =0; i < 100000;i++) { testHex(strs); } System.out.println("Hex: " + (System.currentTimeMillis() - t)); t = System.currentTimeMillis(); for (int i =0; i < 100000;i++) { testBase64(strs); } System.out.println("Base64: " + (System.currentTimeMillis() - t)); } public static void stringManipulation(String[] strs) { String result = serialize(strs); unserialize(result); } private static String[] unserialize(String result) { int sizesSplitPoint = result.toString().lastIndexOf('$'); String sizes = result.substring(sizesSplitPoint+1); StringTokenizer st = new StringTokenizer(sizes, ";"); String[] resultArray = new String[st.countTokens()]; int i = 0; int lastPosition = 0; while (st.hasMoreTokens()) { String stringLengthStr = st.nextToken(); int stringLength = Integer.parseInt(stringLengthStr); resultArray[i++] = result.substring(lastPosition, lastPosition + stringLength); lastPosition += stringLength; } return resultArray; } private static String serialize(String[] strs) { StringBuilder sizes = new StringBuilder("$"); StringBuilder result = new StringBuilder(); for (String str : strs) { if (sizes.length() != 1) { sizes.append(';'); } sizes.append(str.length()); result.append(str); } result.append(sizes.toString()); return result.toString(); } public static void testBase64(String[] strs) throws IOException, ClassNotFoundException, DecoderException { // serialize ByteArrayOutputStream out = new ByteArrayOutputStream(); new ObjectOutputStream(out).writeObject(strs); // your string String yourString = new String(Base64.encodeBase64(out.toByteArray())); // deserialize ByteArrayInputStream in = new ByteArrayInputStream(Base64.decodeBase64(yourString.getBytes())); } public static void testHex(String[] strs) throws IOException, ClassNotFoundException, DecoderException { // serialize ByteArrayOutputStream out = new ByteArrayOutputStream(); new ObjectOutputStream(out).writeObject(strs); // your string String yourString = new String(Hex.encodeHex(out.toByteArray())); // deserialize ByteArrayInputStream in = new ByteArrayInputStream(Hex.decodeHex(yourString.toCharArray())); } } 
+11
source

I would use a character between words to later use the String#split method to return a string. Based on the $ character example, this will be

 public String mergeStrings(String[] ss) { StringBuilder sb = new StringBuilder(); for(String s : ss) { sb.append(s); sb.append('$'); } return sb.toString(); } public String[] unmergeStrings(String s) { return s.split("\\$"); } 

Note that in this example, I add a double \ in front of the $ character, because the String#split method accepts the regular expression as a parameter, and the $ character is a special character in the regular expression.

 public String processData(String[] ss) { String mergedString = mergeStrings(ss); //process data... //a little example... for(int i = 0; i < mergedString.length(); i++) { if (mergedString.charAt(i) == '$') { System.out.println(); } else { System.out.print(mergedString.charAt(i)); } } System.out.println(); //unmerging the data again String[] oldData = unmergeStrings(mergedString); } 

To support any character in your String[] , it would be better to set not one character as a separator, but another String . Methods would turn into this:

 public static final String STRING_SEPARATOR = "@|$|@"; public static final String STRING_SEPARATOR_REGEX = "@\\|\\$\\|@"; public String mergeStrings(String[] ss) { StringBuilder sb = new StringBuilder(); for(String s : ss) { sb.append(s); sb.append(STRING_SEPARATOR); } return sb.toString(); } public String[] unmergeStrings(String s) { return s.split(STRING_SEPARATOR_REGEX); } 
0
source

Use a Json parser such as Jackson to serialize / deserialize objects of a different type, as well as integers / floats ext for strings and vice versa.

0
source

Just use a well-known separator (e.g. @ or # to add your lines) and then use yourString.split (yourSeparator) to get an array from it.

-one
source

All Articles