0

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.

4
  • 3
    I know it is difficult as a beginner, but you are unlikely to receive help if you don't post any of your ideas and attempts. Since you spent hours on this, share with us what you did and why it didn't work. Commented Sep 20, 2015 at 12:00
  • Current progress included Commented Sep 20, 2015 at 12:21
  • Your data model ... is kind of a mess. You're using a simple array to model a series of hierarchical relationships. The solution to your problem with arrays would very likely involve very complex and very fragile code that would be hard to maintain. The right thing to do, rather than worry about arrays, is refactor your problem domain into a domain object model that would enable a solution which would be more elegant and wouldn't require so much effort. Commented Sep 20, 2015 at 12:47
  • How you are determining super class Commented Sep 20, 2015 at 13:18

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.