简体   繁体   中英

Java, Format Array of strings

I have a java String array which contains values like below :

  arr[0] = "ClassA -> ClassSuper";
  arr[1] = "ClassSuperSuper -> ClassSuperSuperSuper";
  arr[2] = "ClassC -> Java/lang/object";
  arr[3] = "ClassSuper -> ClassSuperSuper";

If the array is like above, I want to format this array into a form which reflects the relationship between the values of the above array. Relationship in the sense, for each class; super classes of that class should be appended to theright.

As an example i want to format the above array as follows :

  arr[0] = "ClassA -> ClassSuper-> ClassSuperSuper -> ClassSuperSuperSuper";
  arr[1] = "ClassSuperSuper -> ClassSuperSuperSuper";
  arr[2] = "ClassC -> Java/lang/object";
  arr[3] = "ClassSuper -> ClassSuperSuper -> ClassSuperSuper";

Please help me on this. I'm a newbie to java an spent hours on this but still couldn't succeed. This is what I have done till now.

for(int t=0; t<superOrInterfaceList.length;t++) {
   if(superOrInterfaceList[t] != null) {
      String co = superOrInterfaceList[t].substring((superOrInterfaceList[t].lastIndexOf('>')+1),superOrInterfaceList[t].length());

      for(int s=0; s<superOrInterfaceList.length;s++) {
          if(superOrInterfaceList[s] != null) {
              String cof = superOrInterfaceList[s].substring(0,(superOrInterfaceList[s].indexOf('-')));
              if(cof.equals(co)) {
                  superOrInterfaceList[t] = superOrInterfaceList[t]+"->"+cof;

              }
          }
       }

   }
}

But I'm getting some weird kind of values in my array after executing this loop. It does find a super class only for 1 level and then repeatedly append it again and again. I'm getting answers like bellow when I print the array after running the above code.

"ClassA-> ClassSuper -> ClassSuper -> ClassSuper ..."

Please help me to correct my code. Or if you have another good way please let me know. If you need any more clarifications to answer this please ask.

As scottb said, a better data model can save you a lot of work:

static class AClass {
    private String name;
    private AClass superClass;

    public AClass(String name) {
        this.name = name;
    }

    public void setSuperClass(AClass superClass) {
        this.superClass = superClass;
    }

    @Override
    public String toString() {
        return name + (superClass != null ? " -> " + superClass : "");
    }
}

// return an object from the map if present; otherwise create, insert and return a new one
private static AClass getOrCreate(String name, Map<String, AClass> map) {
    AClass result = map.get(name);
    if (result == null) {
        result = new AClass(name);
        map.put(name, result);
    }
    return result;
}

public static void main(String[] args) {
    String[] arr = {"A -> B", "C -> D", "D -> E", "B -> C"};
    Map<String, AClass> map = new HashMap<>();

    for (String s : arr) {
        String[] split = s.split("\\s+->\\s+"); // split into [subclass, superclass]
        AClass superClass = getOrCreate(split[1], map);
        getOrCreate(split[0], map).setSuperClass(superClass);
    }
    for (AClass c : map.values()) {
        System.out.println(c);
    }
}

See Pattern for details about the regex used in split() , or javadoc for any classes and methods you need.

This example prints all the mentioned classes, which in this case includes E , even if they don't have a superclass. It also prints them in an undefined order. These things should not be difficult to change if needed.

excuse me for disregarding the attmpt of OP.
I solved the problem. I added as much documentation to the code.
Hope OP learns something...

public static void main(String[] args)
{
    String[] arr = new String[4];
    arr[0] = "ClassA -> ClassSuper";
    arr[1] = "ClassSuperSuper -> ClassSuperSuperSuper";
    arr[2] = "ClassC -> Java/lang/object";
    arr[3] = "ClassSuper -> ClassSuperSuper";

    int linkLeafIndex, linkRootIndex;
    do {
        // find a "link": leaf (class name at the end) and root (class name at the start) that are equal
        linkLeafIndex = -1;
        linkRootIndex = -1;
        for (int i = 0 ; i < arr.length ; i++) {
            String leaf = getOneClassName(arr[i], Integer.MAX_VALUE);
            for (int j = 0 ; j < arr.length ; j++) {
                if (j != i) {
                    String root = getOneClassName(arr[j], 0);
                    if (leaf.equals(root)) {
                        linkLeafIndex = i;
                        linkRootIndex = j;
                    }
                }
            }
        }

        // if found, merge the two chains 
        if (linkLeafIndex > -1) {
            // since we link two entries, linked array will have length-1;
            String[] tempArr = new String[arr.length-1];
            // put the merged chain first
            tempArr[0] = linkChains(arr[linkLeafIndex], arr[linkRootIndex]);
            // copy all the rest
            int tempArrIndex = 1 ;
            for (int i = 0 ; i < arr.length ; i++) {
                if (i != linkLeafIndex && i != linkRootIndex) tempArr[tempArrIndex++] = arr[i]; 
            }
            // prepare for next iteration
            arr = tempArr;
        }
    // exit the loop when no more links are found
    } while (linkLeafIndex > -1);

    for (int i = 0 ; i < arr.length ; i++) {
        System.out.println(arr[i]); 
    }
}

// extract either a root or leaf class name 
private static String getOneClassName(String chain, int requiredIndex)
{
    String[] classNames = chain.split("->");
    return requiredIndex < classNames.length ? classNames[requiredIndex].trim() : classNames[classNames.length-1].trim() ;
}

// as the name suggests: create a chain out of merging two given Strings 
private static String linkChains(String startChain, String endChain)
{
    String[] startClassNames = startChain.split("->");
    String[] endClassNames = endChain.split("->");
    String[] linkedClassNames = new String[startClassNames.length + endClassNames.length - 1];

    // copy entire starting chain 
    int linkedClassNamesIndex = 0 ;
    for (int i = 0 ; i < startClassNames.length ; i++) {
        linkedClassNames[linkedClassNamesIndex++] = startClassNames[i].trim();
    }
    // copy ending chain without its root 
    for (int i = 1 ; i < endClassNames.length ; i++) {
        linkedClassNames[linkedClassNamesIndex++] = endClassNames[i].trim();
    }
    // create the required String representation  
    String linkedChain = "";
    for (int i = 0 ; i < linkedClassNames.length ; i++) {
        linkedChain += linkedClassNames[i];
        if (i < linkedClassNames.length-1) {
            linkedChain += " -> ";
        }
    }
    return linkedChain;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM