在Java中将String转换为嵌套的ArrayList

时间:2016-05-15 07:00:56

标签: java string recursion arraylist nested

我有一个字符串:

    String input = {{a,b,c}, 4,6, 7 , {c, d, {g,h, {} }}};

我需要转换'输入'嵌入的ArrayList,其中每个' {}'在一个单独的列表中。请注意,输入中有随机空格,需要在添加List中的每个元素之前进行修剪。 因此,需要的输出(在toString()方法中描述的输出表示):

    List<Object> output = [[a,b,c],4,6,7,[c,d,[g,h,[]]]]

这里,每个元素都是一个列表项。所以

    List<Object> emptyList = []
    List<Object> subList1 = [g,h,emptyList]
    List<Object> subList2 = [c,d,subList1]
    List<Object> subList3 = [a,b,c]
    List<Object> parentList = [sublist3,4,6,7,sublist2]

我只需要将最后一个/父列表作为&#39; parentList&#39;以上,中间结果可以忽略 有人可以用一个简洁的算法帮我解决这个问题。我已经尝试了几个小时,但未能派生一个正确的递归调用方法解决方案。然而,最受欢迎的是非递归方法解决方案:)

我尝试使用以下代码。虽然,它有点粗糙。

    package com.psl.demo;

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;

    public class ListClass {

        public List<Object> converToList(String string){
            List<Object> list = new ArrayList<Object>();

            string = string.trim();
            StringBuilder sb = new StringBuilder(string);

            List<Integer> startIndices= new ArrayList<Integer>();
            List<Integer> endIndices = new ArrayList<Integer>();

            int counter = 0;
            while(counter < sb.length()){
                if(sb.charAt(counter) == '{'){
                    startIndices.add(counter);
                    sb.setCharAt(counter, ' ');
                }
                counter++;
            }

            int reverseCounter = sb.length()-1;
            while(reverseCounter > 0){
                if(sb.charAt(reverseCounter) == '}'){
                    endIndices.add(reverseCounter);
                    sb.setCharAt(reverseCounter, ' ');
                }
                reverseCounter--;
            }

            if(startIndices.size() != endIndices.size()){
                System.out.println("Brackets do not match. exiting");
                System.exit(1);
            }


            int size = startIndices.size();
            counter = 0;
            reverseCounter = size-1;
            for(int i=0; i<size; i++){
                String contents =                 sb.substring(startIndices.get(reverseCounter), endIndices.get(counter));
                //sb.replace(startIndices.get(reverseCounter),         endIndices.get(counter),"");
                contents = contents.trim();
                List<Object> subList = new ArrayList<Object>();
                Object[] tokens = contents.split(",");
                for(int j=0; j< tokens.length;j++){
                    tokens[j] = tokens[j].toString().trim();
                }
                subList = Arrays.asList(tokens);
                list.add(subList);
                counter++;

                reverseCounter--;
            }

            Collections.reverse(list);
            return list;
        }

        public static void main(String[] args) {
            String string = "{{a ,b, {hello, world}},  4 ,6,  7, { c , d }         }";
            ListClass obj = new ListClass();
            List<Object> list= obj.converToList(string);
            System.out.println(list);
        }

    }

请忽略代码的System.exit()部分。这将被适当的代码所取代。 由于我提到的特定要求,使用了对象类型列表。

2 个答案:

答案 0 :(得分:0)

您尝试做的事情似乎与JSON反序列化非常相似。如果ab等用引号括起来,您可以使用Jackson

    import com.fasterxml.jackson.databind.ObjectMapper;
    // ...
    ObjectMapper jsonMapper = new ObjectMapper();
    String content = "{{\"a\",\"b\",\"c\"}, 4,6, 7 , {\"c\", \"d\", {\"g\", \"h\", {} }}}";
    String contentWithBrackets = content.replace('{', '[').replace('}',']');
    List list =  jsonMapper.readValue(contentWithBrackets, List.class);
    System.out.println(list); // [[a, b, c], 4, 6, 7, [c, d, [g, h, []]]]

答案 1 :(得分:0)

这可能类似于DS中的表达式评估。所以我认为你需要使用 Stack 数据结构来解决这类问题。尝试使用以下代码,它可以解决您的问题。

package src.com;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
public class Abc {      
    public static class Bean {
        int token;
        Object obj;
        public Bean(){}
        public Bean(int token, Object o) {
            super();
            this.token = token;
            this.obj = o;
        }
    }
    public static void main(String[] args) {
        String input = "{{a,b,c},4, 6,7,{d,e,{},{ }}}";
        input = input.replaceAll(" ", "");
        List<Object> list = getList(input);
        System.out.println(list);
    }
    @SuppressWarnings("unchecked")
    public static List<Object> getList(String input1) {
        Deque<Object> stack = new ArrayDeque<Object>();
        char[] chararray = input1.toCharArray();
        String temp = "";
        for (int i = 0; i < chararray.length; i++) {
            if (chararray[i] == '}') {
                if (!temp.equals("")) {
                    stack.push(new Bean(0, temp));
                    temp = "";
                }
                List<Object> tmplist = new ArrayList<>();
                while (true) {
                    Object object = stack.pop();
                    if (object instanceof Bean) {
                        Bean b = (Bean) object;
                        if (b.token == 1)
                            break;
                        tmplist.add(b.obj);
                    } else {
                        tmplist.add(object);
                        if (stack.isEmpty())
                            break;
                    }
                }
                Collections.reverse(tmplist);
                stack.push(tmplist);
            } else {
                if (chararray[i] == '{') {
                    stack.push(new Bean(1, Character.toString(chararray[i])));
                } else if (chararray[i] == ',') {
                    if (!temp.equals("")) {
                        stack.push(new Bean(0, temp));
                        temp = "";
                    }
                } else {
                    temp = temp + Character.toString(chararray[i]);
                }
            }
        }
        return (List<Object>) stack.pop();
    }
}