在Java中将数组字符串转换为字符串并返回

我在Java中有一个数组String [],必须首先将其编码/转换为String,然后在代码中进一步将其转换回String []数组。 问题是我可以在String []数组中的字符串中包含任何字符,因此编码时必须非常小心。 解码它所需的所有信息必须在最终的字符串中。 我不能在额外的变量中返回字符串和其他一些信息。

到目前为止,我设计的算法是:

  1. 将所有字符串附加到彼此旁边,例如:String [] a = {“lala”,“exe”,“a”}到字符串b =“lalaexea”

  2. 在字符串的末尾附加String []中所有字符串的长度,通过$符号与主文本分隔,然后用逗号分隔每个长度,所以:

b =“lalaexea $ 4,3,1”

然后在转换回来的时候,我会首先从后面读取长度,然后根据它们,真正的字符串。

但也许有一种更简单的方法?

干杯!

如果你不想花太多时间在字符串操作上,可以使用java serialization + commons codecs,如下所示:

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

这将返回以下输出:

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

如果您使用的是maven,则可以对commons编解码器使用以下依赖项:

  commons-codec commons-codec 1.2  

正如base64建议的那样(两行改变):

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

对于Base64,结果字符串更短,对于下面公开的代码:

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

关于每种方法的时间,我对每种方法执行10 ^ 5次执行,结果如下:

  • 字符串操作:156毫秒
  • hex:376毫秒
  • Base64:379毫秒

用于测试的代码:

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

我会使用单词之间的符号稍后使用String#split方法来获取String。 基于您的$符号示例,它将是

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

请注意,在此示例中,我在$符号之前添加了一个double \ ,因为String#split方法接收正则表达式作为参数, $符号是正则表达式中的特殊字符。

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

为了支持String[]任何字符,最好不要将单个字符设置为分隔符,而是设置另一个String 。 方法会变成这样:

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

使用像Jackson这样的Json解析器来序列化/反序列化其他类型的对象,以及整数/浮点数转换为字符串和返回。

只需使用已知的分隔符(例如@#来附加字符串),然后使用yourString.split(yourSeparator)从中获取数组。