Google

May 24, 2014

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

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

1. Allows you to maintain a parent/child hierachy 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.

In the previous parts
In this part, you will be adding an add(...) method to add an item to the hierarchical list.


Step 1: Remove the UnsupportedOperationException with the following recursive method call. Recursion is used to add to the parent and children.

//....removed methods

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

    //...removed constructors & methos  

 @Override
 public boolean add(E e) {
  return add(e, null);
 }
 
 protected boolean add(E e, CustomList<E> givenList) {

  // check if the predicate (i.e. condition) is met
  if (!evaluate(e)) {
   return false;
  }

  boolean hasAdded = true;

  // if parent exists, add to the parent
  if (parent != null && parent != givenList) {
   // Recursive method call. The parent takes care of siblings...
   hasAdded = parent.add(e, this);
  }

  // if addition fails, return false
  if (!hasAdded) {
   return false;
  }

  //add it to the actual list
  hasAdded = this.list.add(e);

  if (!hasAdded) {
   if (parent != null) {
    throw new IllegalStateException("Failed to add !!");
   } else {
    return false;
   }
  }

  // Add to the sublists
  for (CustomList<E> sublist : sublists) {
   if (sublist != givenList) {
    // recursive method call
    sublist.add(e, this);
   }
  }

  return true;
 }

 private boolean evaluate(E e) {
  return (this.predicate != null) ? this.predicate.evaluate(e) : true;
 }
 
 
 //...removed some methods 
}





Step 2: The CustomListTest that adds items to the CustomList. Note that the initial list creation was slightly modified to make "initialList" mutable, so that new items can be added.

package test;

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

public class CustomListTest {

 public static void main(String[] args) {
  /**
   * Arrays.asList returns a List wrapper around an array. This wrapper
   * has a fixed size and is directly backed by the array, and as such
   * calls to set will modify the array, and any other method that
   * modifies the list will throw an UnsupportedOperationException.
   * hence creating a new ArrayList(...) instance
   */
  List<Integer> initialList = new ArrayList<Integer>(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);

  // add an item or element
  customList.add(11); // this should be added to customList and
       // oddNumbersSubList
  customList.add(15); // this should be added to all four lists.

  System.out.println("After adding 11 & 15: ");
  System.out.println("customList : " + customList);
 }
}

The output is:

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]

After adding 11 & 15: 
customList : list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15]
child: [1, 3, 5, 7, 9, 11, 15]
child: [5, 10, 15]
child: [3, 9, 15]

Labels:

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home