将两个String分成子串并将它们配对

时间:2016-08-03 08:37:03

标签: java string dictionary substring

我正在为这个问题寻找有趣的解决方案:

String key = "1;2;3;4";
String value = "Value1;Value2;Value whitespace;"

现在';'将每个值与另一个值分开。相同的符号';'也把钥匙分开了。

现在我想结束:

{"1" : "Value1", "2" : "Value2", "3" : "Value whitespace", "4" : null}

当然,如果值多于键,那么null应该不是该对的左侧(null:" Value5")。

我使用char数组为这个问题做了一个非常复杂的解决方案但是有很多案例和东西的一个大FOR(它是O(n))。所以我很想看到正则表达式或子字符串解决方案或不包含大循环的东西。

编辑: 矿井解决方案:

private List<ExampleObject> getExampleObjects(String key , String value) {
    // s
    if (key  == null || value == null) {
        return new ArrayList<ExampleObject>();
    }

    List<ExampleObject> exampleObjects = new ArrayList<ExampleObject>();

    char[] keyToCharArray = key.toCharArray();
    char[] valueToCharArray = value.toCharArray();

    StringBuilder name = new StringBuilder();
    StringBuilder value = new StringBuilder();

    boolean nameCompleted = false;
    boolean valueCompleted = false;

    for (int i = 0, j = 0; i < keyToCharArray.length || j < valueToCharArray.length;) {
        if (!nameCompleted) {
            char a = ' ';
            try{
                 a = keyToCharArray[i];
            } catch(Exception e){
                 a = ';';
                // throw : VALES and key  not match. More key  then value
                //throw(e);
            }

            if (a == ';' ) {
                nameCompleted = true;
            } else if (!(i + 1 < keyToCharArray.length)){
                name.append(a);
                nameCompleted = true;
            }   else {
                name.append(a);

            }
            i++;
        }
        if (!valueCompleted) {

            char a = ' ';
            try{
                 a = valueToCharArray[j];
            } catch(Exception e){
                 a = ';';
                // throw : VALES and key  not match. More value then key 
                //throw(e);
            }

            if (a == ';') {
                valueCompleted = true;
            } else if(!(j + 1 < valueToCharArray.length)) {
                value.append(a);
                valueCompleted = true;
            } else {
                value.append(a);
            }
            j++;
        }
        if (nameCompleted && valueCompleted) {
            exampleObjects.add(new ExampleObject(name.toString(), value.toString()));
            name.setLength(0);
            value.setLength(0);
            nameCompleted = false;
            valueCompleted = false;
        }
    }
    return exampleObjects;
}

其中 ExampleObject.class 包含字段 key value

5 个答案:

答案 0 :(得分:3)

我已经找到了解决问题的方法:

<强>输出

{"1" : "Value1", "2" : "Value2", "3" : "Value whitespace", "4" : "null"}       

<强>代码

public class HelloWorld{

     public static void main(String []args){
        String key = "1;2;3;4";
        String value = "Value1;Value2;Value whitespace;";

        String[] keyArr = key.split(";");
        String[] valueArr = value.split(";");

        String finalJSON = "{";
        for(int i=0; i<(keyArr.length > valueArr.length ? keyArr.length : valueArr.length); i++) {

            try {
                finalJSON += "\"" + keyArr[i] + "\"";
            }
            catch(ArrayIndexOutOfBoundsException e) {
                finalJSON += "\"null\"";
            }

            finalJSON += " : ";

            try {
                finalJSON += "\"" + valueArr[i] + "\"";
            }
            catch(ArrayIndexOutOfBoundsException e) {
                finalJSON += "\"null\"";
            }
            if(i!=(keyArr.length > valueArr.length ? keyArr.length : valueArr.length) - 1) 
                finalJSON += ", ";
        }
        finalJSON += "}";

        System.out.println(finalJSON);
     }
}

答案 1 :(得分:2)

Java 8:

String key = "1;2;3;4";
String value = "Value1;Value2;Value whitespace;";
String[] keys = key.split(";", -2);
String[] values = value.split(";", -2);

Map<String, String> result = IntStream.range(0, keys.length).mapToObj(i->i).collect(Collectors.toMap(i->keys[i], i-> values[i]));
result.entrySet().forEach(e->result.put(e.getKey(), e.getValue().length()==0 ? null : e.getValue()));

答案 2 :(得分:2)

另一个 - 尽可能优雅的Java8和Generic。

/**
 * General pair of items.
 *
 * @param <P> - Type of the first item in the pair.
 * @param <Q> - Type of the second item.
 */
static class Pair<P, Q> {
    final P p;
    final Q q;

    public Pair(P p, Q q) {
        this.p = p;
        this.q = q;
    }

    @Override
    public String toString() {
        return "{" + p + "," + q + "}";
    }
}

/**
 * Gets the `n`th item is present in the array - otherwise returns null.
 *
 * @param a   - The array
 * @param n   - Which one in the array we want.
 * @param <T> - The type of the array entries.
 * @return - The `n`th entry in the array or null if not present.
 */
private static <T> T n(T[] a, int n) {
    return n < a.length ? a[n] : null;
}

/**
 * Pairs up each element in the arrays.
 *
 * @param <P> - The type of the elements in the `P` array.
 * @param <Q> - The type of the elements in the `Q` array.
 * @param ps  - The `P` array.
 * @param qs  - The `Q` array.
 * @return A list of `Pair`s of each element.
 */
static <P, Q> List pairUp(P[] ps, Q[] qs) {
    return IntStream.range(0, Math.max(ps.length, qs.length))
            .mapToObj(i -> new Pair<>(n(ps, i), n(qs, i)))
            .collect(Collectors.toList());
}

/**
 * Splits the two strings on a separator and returns a list of Pairs of the corresponding items.
 *
 * @param a         - The first string.
 * @param b         - The second string.
 * @param separator - The separator.
 * @return - A List of Paired up entries from `a` and `b`.
 */
private static List<Pair<String, String>> fold(String a, String b, String separator) {
    return pairUp(a.split(separator, -1), b.split(separator, -1));
}

public void test() {
    System.out.println(fold("1;2;3;4", "Value1;Value2;Value whitespace", ";"));
}

答案 3 :(得分:1)

尝试以下操作:(如果你想按照你的说法打印一个字符串)

  1. 使用String#split()
  2. 将两个字符串拆分为数组
  3. value[]key[]
  4. 创建计数器
  5. 创建boolean以指示是否附加了键或值
  6. 使用StringBuilder并循环键[]
  7. 的长度
  8. 附加内容
  9. 使用String
  10. 返回新的StringBuilder#append()

    完成。在检查解决方案之前尝试一下!

    StringBuilder:https://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html
    字符串:https://docs.oracle.com/javase/7/docs/api/java/lang/String.html

    我打印出字符串的解决方案:

    public static void main(String[] args) {
        String key = "1;2;3;4";
        String value = "Value1;Value2;Value whitespace";
    
        String[] keys = key.split(";");
        String[] values = value.split(";");
    
        StringBuilder sb = new StringBuilder("{");
        boolean isKey = true;
        int keyCount = 0;
        int valueCount = 0;
    
        for(int i = 0; i < key.length(); i++) {
            sb.append("\"");
    
            if(isKey) {
                sb.append(keys[keyCount]).append("\" : ");
                keyCount++;
            } else {
                sb.append(values[valueCount]).append("\", ");
                valueCount++;
            }
            isKey = !isKey;
        }
    
        sb.append("}");
        System.out.println(sb.toString());
    }
    

答案 4 :(得分:1)

另一种观点:不要“手动”做这些事情。

我的意思是:不要自己做所有“低级别”操作;你应该抽象。

首先,将您的键值字符串转换为地图。像:

   ·   Automatically bisect with temporary modifications (hot-fix):

           $ cat ~/test.sh
           #!/bin/sh

           # tweak the working tree by merging the hot-fix branch
           # and then attempt a build
           if      git merge --no-commit hot-fix &&
                   make
           then
                   # run project specific test and report its status
                   ~/check_test_case.sh
                   status=$?
           else
                   # tell the caller this is untestable
                   status=125
           fi

           # undo the tweak to allow clean flipping to the next commit
           git reset --hard

           # return control
           exit $status

然后最后,使用一些现有的JSON库来简单地基于该映射生成JSON表示。

换句话说:除非你在谈论有数百万条目的名单;不要担心性能。相反,担心良好的抽象,而不是重新发明轮子和代码可读性。

但是如果你真的不得不担心性能或内存方面,那么只需拆分成数组,然后使用这两个数组作为一些使用StringBuilder构建所需输出字符串的函数的输入。