Google

May 20, 2014

Core Java Coding Questions: Creating a custom hierarchical List in Java -- Part 2

This is an extension to Core Java Coding Questions: Creating a custom hierarchical List in Java -- Part 1, which answers the following question.

Q. Can you write a custom list class that supports following features?

1. Allows you to maintain a parent/child hierarchy of sub lists.
2. Allows you to create sublists from a given list and a predicate (i.e a condition)
3. If you add an item or element to a list, the addition must be propagated to its parent and child lists.
4. If you remove an element from a list, the removal must be propagated to its parent and child lists.


This part extends the very simple toString( ) method to print the list hierarchy including both parent and child. It is not easy to work with hierarchical structures, and that is why interviewers love to ask these questions. Here, I am using an iterative approach as opposed to recursion. Search this blog for recursion, and see if you can solve this with recursion. Also, pay attention to Generics.

Here is the revised CustomList class only showing the toString( ) and its dependent private methods.



package test;

//... removed for brevity

public class CustomList<E> implements List<E> {

 private CustomList<E> parent = null; // parent
 protected List<E> list = null; // initial list
 private List<CustomList<E>> sublists = new ArrayList<CustomList<E>>(); // children
 private Predicate<E> predicate; // used to create sublists based on the
         // predicate

 
 //.... removed for brevity
 
 
 /**
  * advanced toString() method
  */
 @Override
 public String toString() {
  StringBuilder sb = new StringBuilder();

  Deque<CustomList<Integer>> allParents = getAllParents();

  while (!allParents.isEmpty()) {
   CustomList<Integer> parent = allParents.pop();
   sb.append("parent: " + parent.list.toString() + "\n");
  }

  sb.append("list: " + list.toString() + "\n");

  Deque<CustomList<Integer>> allChildren = getAllChildren();
  while (!allChildren.isEmpty()) {
   CustomList<Integer> child = allChildren.remove();
   sb.append("child: " + child.list.toString() + "\n");
  }
  return sb.toString();
 }

 @SuppressWarnings("unchecked")
 private Deque<CustomList<Integer>> getAllParents() {
  Deque<CustomList<Integer>> queue = new ArrayDeque<CustomList<Integer>>();
  CustomList<Integer> currentCs = (CustomList<Integer>) this;

  // push each parent to the stack
  while (currentCs != null && currentCs.parent != null) {
   queue.push(currentCs.parent);
   currentCs = currentCs.parent;
  }

  return queue;
 }

 @SuppressWarnings("unchecked")
 private Deque<CustomList<Integer>> getAllChildren() {
  Deque<CustomList<Integer>> queue = new ArrayDeque<CustomList<Integer>> ();    //for processing iteratively
  Deque<CustomList<Integer>> queueResult = new ArrayDeque<CustomList<Integer>> (); //for holding the results

  if (this != null) {
   queue.push((CustomList<Integer>) this);
  }

  while (!queue.isEmpty()) {
   CustomList<Integer> cl = queue.pop();
   if (cl.sublists != null) {
    for (CustomList<Integer> child: cl.sublists) {
     queue.push(child);
     queueResult.add(child);
    }
   }

  }

  return queueResult;
 }

}


Repeating the main test class from the  Creating a custom hierarchical List in Java -- Part 1.


package test;

import java.util.Arrays;
import java.util.List;

public class CustomListTest {
 
 
 public static void main(String[] args) {
  List<Integer> initialList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
 
  CustomList<Integer> customList = new CustomList<Integer>(initialList);
  System.out.println("customList: " + customList);
  
  Predicate<Integer> oddNumberPredicate = new OddNumberPredicate<Integer>();
  CustomList<Integer> oddNumbersSubList = customList.subList(oddNumberPredicate);
  System.out.println("oddNumbersSubList: " + oddNumbersSubList);
  
  Predicate<Integer> factorOf5Predicate = new FactorOf5Predicate<Integer>();
  CustomList<Integer> factorOf5SubList = customList.subList(factorOf5Predicate);
  System.out.println("factorOf5SubList: " + factorOf5SubList);
  
  
  Predicate<Integer> factorOf3Predicate = new FactorOf3Predicate<Integer>();
  CustomList<Integer> factorOf3SubList = oddNumbersSubList.subList(factorOf3Predicate);
  System.out.println("factorOf3SubList : " + factorOf3SubList);
  
  
  System.out.println("Demonstrate printing customList again");
  System.out.println("customList : " + customList);
  
 }

}





Now the revised output will have parent child hierarchical information as shown below.

customList: list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]



oddNumbersSubList: parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list: [1, 3, 5, 7, 9]



factorOf5SubList: parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list: [5, 10]



factorOf3SubList : parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

parent: [1, 3, 5, 7, 9]

list: [3, 9]



Demonstrate printing customList again

customList : list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

child: [1, 3, 5, 7, 9]

child: [5, 10]

child: [3, 9]

Labels: ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home