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

Jan*_*nek 9 java string encoding

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

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

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

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

b ="lalaexea $ 4,3,1"

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

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

干杯!

Fra*_*eth 12

如果你不想在字符串操作上花那么多时间,你可以使用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()));
}
Run Code Online (Sandbox Code Playgroud)

这将返回以下输出:

[test 1, test 2, test 3]
aced0005757200135b4c6a6176612e6c616e672e537472696e673badd256e7e91d7b47020000787000000003740006746573742031740006746573742032740006746573742033
[test 1, test 2, test 3]
Run Code Online (Sandbox Code Playgroud)

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

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.2</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

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

String yourString = new String(Base64.encodeBase64(out.toByteArray()));
ByteArrayInputStream in = new ByteArrayInputStream(Base64.decodeBase64(yourString.getBytes()));
Run Code Online (Sandbox Code Playgroud)

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

[test 1, test 2, test 3]
rO0ABXVyABNbTGphdmEubGFuZy5TdHJpbmc7rdJW5+kde0cCAAB4cAAAAAN0AAZ0ZXN0IDF0AAZ0ZXN0IDJ0AAZ0ZXN0IDM=
[test 1, test 2, test 3]
Run Code Online (Sandbox Code Playgroud)

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

  • 字符串操作:156毫秒
  • 十六进制: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()));
    }

}
Run Code Online (Sandbox Code Playgroud)