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

在Java中将数组字符串转换为字符串并返回,java,string,encoding,Java,String,Encoding,我在Java中有一个数组字符串[],必须首先将其编码/转换为字符串,然后在代码中进一步将其转换回字符串[]数组。问题是,我可以在string[]数组中的字符串中包含任何字符,因此在编码时必须非常小心。解码所需的所有信息都必须在最后一个字符串中。我不能在额外变量中返回字符串和其他信息 到目前为止,我设计的算法是: 将所有字符串相邻附加,例如: 字符串[]a={“lala”,“exe”,“a”} 进入 字符串b=“laexea” 在字符串末尾追加字符串[]中所有字符串的长度,以$符号与正文分隔,然后

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

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

  • 将所有字符串相邻附加,例如: 字符串[]a={“lala”,“exe”,“a”} 进入 字符串b=“laexea”

  • 在字符串末尾追加字符串[]中所有字符串的长度,以$符号与正文分隔,然后每个长度以逗号分隔,因此:

  • b=“Laexea$4,3,1”

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

    但也许有更简单的方法


    干杯

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

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

    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("\\$");
    }
    
    注意,在本例中,我在
    $
    符号之前添加了一个双精度
    \
    ,因为
    String#split
    方法接收一个正则表达式作为参数,
    $
    符号是regex中的一个特殊字符

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

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

    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编解码器使用以下依赖项:

    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.2</version>
    </dependency>
    
    对于Base64,对于下面公开的代码,结果字符串更短:

    [test 1, test 2, test 3]
    rO0ABXVyABNbTGphdmEubGFuZy5TdHJpbmc7rdJW5+kde0cCAAB4cAAAAAN0AAZ0ZXN0IDF0AAZ0ZXN0IDJ0AAZ0ZXN0IDM=
    [test 1, test 2, test 3]
    
    关于每种方法的时间,我对每种方法执行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()));
        }
    
    }
    
    import java.io.ByteArrayInputStream;
    导入java.io.ByteArrayOutputStream;
    导入java.io.IOException;
    导入java.io.ObjectOutputStream;
    导入java.util.StringTokenizer;
    导入org.apache.commons.codec.DecoderException;
    导入org.apache.commons.codec.binary.Base64;
    导入org.apache.commons.codec.binary.Hex;
    公共类StringArrayRepresentationTest{
    publicstaticvoidmain(字符串[]args)抛出IOException、ClassNotFoundException、DecoderException{
    字符串[]strs=新字符串[]{“测试1”、“测试2”、“测试3”};
    long t=System.currentTimeMillis();
    对于(int i=0;i<100000;i++){
    字符串操纵(strs);
    }
    System.out.println(“字符串操作:”+(System.currentTimeMillis()-t));
    t=System.currentTimeMillis();
    对于(int i=0;i<100000;i++){
    testHex(strs);
    }
    System.out.println(“十六进制:”+(System.currentTimeMillis()-t));
    t=System.currentTimeMillis();
    对于(int i=0;i<100000;i++){
    testBase64(strs);
    }
    System.out.println(“Base64:”+(System.currentTimeMillis()-t));
    }
    公共静态void stringManipulation(String[]strs){
    字符串结果=序列化(strs);
    未序列化(结果);
    }
    私有静态字符串[]未序列化(字符串结果){
    int-sizesSplitPoint=result.toString().lastIndexOf(“$”);
    字符串大小=结果.子字符串(sizesSplitPoint+1);
    StringTokenizer st=新的StringTokenizer(大小,“;”);
    String[]resultArray=新字符串[st.countTokens()];
    int i=0;
    int lastPosition=0;
    而(st.hasMoreTokens()){
    字符串stringLengthStr=st.nextToken();
    int stringLength=Integer.parseInt(stringLengthStr);
    resultArray[i++]=结果.子字符串(lastPosition,lastPosition+stringLength);
    lastPosition+=字符串长度;
    }
    返回结果数组;
    }
    私有静态字符串序列化(字符串[]strs){
    StringBuilder尺寸=新StringBuilder($);
    StringBuilder结果=新建StringBuilder();
    用于(字符串str:strs){
    如果(size.length()!=1){
    大小。追加(“;”);
    }
    大小。追加(str.length());
    结果:追加(str);
    }
    result.append(size.toString());
    返回result.toString();
    }
    公共静态void testBase64(字符串[]strs)引发IOException、ClassNotFoundException、DecodeException{
    //连载
    ByteArrayOutputStream out=新建ByteArrayOutputStream();
    新的ObjectOutputStream(out).writeObject(strs);
    //你的绳子
    String yourString=新字符串(Base64.encodeBase64(out.toByteArray());
    //反序列化
    ByteArrayInputStream in=newbytearrayinputstream(Base64.decodeBase64(yourString.getBytes());
    }
    公共静态void testHex(字符串[]strs)抛出IOException、ClassNotFoundException、DecoderException{
    //连载
    ByteArrayOutputStream out=新建ByteArrayOutputStream();
    新的ObjectOutputStream(out).writeObject(strs);
    //你的绳子
    String yourString=新字符串(Hex.encodeHex(out.toByteArray());
    //反序列化
    ByteArrayInputStream in=新的ByteArrayInputStream(Hex.decodeHex(yourString.toCharArray());
    }
    }
    
    使用类似Jackson的Json解析器来序列化/反序列化其他类型的对象,以及integer/Float ext到字符串和返回

    OP解释说,在string[]数组中,他可以有字符串中的任何字符,因此在加入之前应该转义所选的分隔符,例如
    s.replaceAll(“\\$”,“\$”)
    @sp00m我希望数据保持不变,而不是建议
    [test 1, test 2, test 3]
    rO0ABXVyABNbTGphdmEubGFuZy5TdHJpbmc7rdJW5+kde0cCAAB4cAAAAAN0AAZ0ZXN0IDF0AAZ0ZXN0IDJ0AAZ0ZXN0IDM=
    [test 1, test 2, test 3]
    
    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()));
        }
    
    }