在Java数组字符串转换为字符串,并回(Converting array string to str

2019-07-03 15:58发布

我有一个数组的String []在Java中,并且必须首先编码/将其转换成一个字符串,然后进一步在代码隐蔽它回到String []数组。 问题是,我可以在String []数组字符串的任何字符,所以我必须编码时非常小心。 和所有必要的信息来进行解码就必须在最后的字符串。 我不能返回一个字符串和一个额外的变量的一些其他信息。

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

  1. 追加的所有字符串彼此旁边,例如是这样的:字符串[] A = {“拉拉”,“执行”,“一个”}到串B =“lalaexea”

  2. 附加在所述串的结尾的所有字符串的长度从字符串[],从由$符号的主文本,然后用逗号分隔的每个长度,如此分离:

B = “lalaexea $ 4,3,1”

然后将其转换回来的时候,我会先看从后面,然后长度基于这些,真正的字符串。

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

干杯!

Answer 1:

如果你不想用字符串操作花了这么多时间,你可以使用Java序列化+ 公地编解码器是这样的:

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,您可以使用公共编解码以下依赖性:

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

正如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毫秒
  • 十六进制: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()));
    }

}


Answer 2:

使用的JSON解析器像杰克逊序列化/反序列化的其他类型的对象,以及像整数/浮动分机为字符串,然后回来。



Answer 3:

我会用的单词之间的符号后使用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方法接收一个正则表达式作为参数,而$符号是正则表达式特殊字符。

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


Answer 4:

只需使用一个已知的分隔符(如@#追加你的字符串),然后使用yourString.split(yourSeparator)从它那里得到一个数组。



文章来源: Converting array string to string and back in Java