One of my hot favorite topic is sorting.
Description of the problem:
1) Imagine a line of containers which are going to be loaded onto the ship. Assume the desired loading sequence is 1,2,3 eg C1 C2 C3 C4 C5 C6
![]()
2) A Container class is has a sequence method .getSeq(). So lets say for C1,
container.getSeq() == 1 For C2, container.getSeq() == 2
If we have an array list:
final List containers = new ArrayList(Arrays.asList(C2, C1, C6, C5, C4, C3));
How do we sort this list? So it’s C1, C2, C3, C4, C5, C6?
Part 2:
Lets say containers in the stack are like:

On top of C2, container C6 is there. we can not lift C2 before lifting the C6.
So C6 must be lifted before C2 – so for this case only C6 must go before C2.
There is a method in the Container class container.getAboveMe()
So for C2, container.getAboveMe() returns a container whitch is C6.
For C1, C2, C3, C4 and C5 container.getAboveMe() returns null.
Similarly getAboveMe(), another method getBelowMe() so for C6.
container.getBelowMe() returns a container which is C2 – every thing else getBelowMe returns null
Java Source Codes :
Container.java
public class Container {
public Container(final int inSequence) {
_sequence = inSequence;
_aboveMe = null;
_belowMe = null;
}
@Override
public String toString() {
return String.valueOf(getSequence());
}
public int getSequence() {
return _sequence;
}
public void setAboveMe(final Container inAboveMe) {
_aboveMe = inAboveMe;
}
public void setBelowMe(final Container inBelowMe) {
_belowMe = inBelowMe;
}
public Container getAboveMe() {
return _aboveMe;
}
public Container getBelowMe() {
return _belowMe;
}
private final int _sequence;
private Container _belowMe;
private Container _aboveMe;
}
SortContainers.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class SortContainers {
public static void doSort( List containers ) {
//Remove all null values from the list
containers.removeAll(Collections.singleton(null));
Collections.sort(containers, new Comparator() {
public int compare(final Container c1, final Container c2) {
if (c1.getAboveMe()!= null && c1.getAboveMe().equals(c2)) {
return 1;
}
if (c2.getAboveMe()!= null && c2.getAboveMe().equals(c1)) {
return -1;
}
int c1Value = c1.getSequence();
int c2Value = c2.getSequence();
if (c1.getBelowMe() != null) {
c1Value = c1.getBelowMe().getSequence();
}
if (c2.getBelowMe() != null) {
c2Value = c2.getBelowMe().getSequence();
}
return c1Value - c2Value;
}
});
}
}
I like Test Driven Development,
I have use cases for this example.
SortContainers.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.testng.annotations.Test;
import static org.junit.Assert.assertEquals;
public class SortContainersSaTest {
@Test
public void testSortContainersCase1() {
final Container C1 = new Container(1);
final Container C2 = new Container(2);
final Container C3 = new Container(3);
final Container C4 = new Container(4);
final Container C5 = new Container(5);
final Container C6 = new Container(6);
final List containers = new ArrayList(Arrays.asList(C2, C1, C6, C5, C4, C3));
SortContainers.doSort( containers );
final List expectedContainers =
new ArrayList(Arrays.asList(C1, C2, C3, C4, C5, C6));
assertEquals( expectedContainers , containers );
}
@Test
public void testSortContainersCase2() {
final Container C1 = new Container(1);
final Container C2 = new Container(2);
final Container C3 = new Container(3);
final Container C4 = new Container(4);
final Container C5 = new Container(5);
final Container C6 = new Container(6);
C6.setBelowMe(C2);
C2.setAboveMe(C6);
final List containers = new ArrayList(Arrays.asList(C2, C1, C6, C5, C4, C3));
SortContainers.doSort( containers );
final List expectedContainers = new ArrayList(Arrays.asList(C1, C6, C2, C3, C4, C5));
assertEquals( expectedContainers , containers );
}
@Test
public void testSortContainersCase3() {
final Container C1 = new Container(1);
final Container C2 = new Container(2);
final Container C3 = new Container(3);
final Container C4 = new Container(4);
final Container C5 = new Container(5);
final Container C6 = new Container(6);
final Container C7 = new Container(7);
C6.setBelowMe(C2);
C2.setAboveMe(C6);
C7.setBelowMe(C4);
C4.setAboveMe(C7);
final List containers =
new ArrayList(Arrays.asList(C2, C1, C6, C7, C5, C4, C3));
SortContainers.doSort( containers );
final List expectedContainers =
new ArrayList(Arrays.asList(C1, C6, C2, C3, C7, C4, C5));
assertEquals( expectedContainers , containers );
}
@Test
public void testSortContainersCase4() {
final Container C1 = new Container(1);
final Container C2 = new Container(2);
final Container C3 = new Container(3);
final Container C4 = new Container(4);
final Container C5 = new Container(5);
final Container C6 = new Container(6);
final Container C7 = new Container(7);
C6.setBelowMe(C2);
C2.setAboveMe(C6);
C4.setBelowMe(C7);
C7.setAboveMe(C4);
final List containers =
new ArrayList(Arrays.asList(C2, C1, C6, C7, C5, C4, C3));
SortContainers.doSort( containers );
final List expectedContainers =
new ArrayList(Arrays.asList(C1, C6, C2, C3, C5, C4, C7));
assertEquals( expectedContainers , containers );
}
@Test
public void testSortContainersCase5() {
final Container C1 = new Container(1);
final Container C2 = new Container(2);
final Container C3 = new Container(3);
final Container C4 = new Container(4);
final Container C5 = new Container(5);
final Container C6 = new Container(6);
final Container C7 = new Container(7);
C6.setBelowMe(C1);
C1.setAboveMe(C6);
final List containers =
new ArrayList(Arrays.asList(C2, C1, C6, C7, C5, C4, C3));
SortContainers.doSort( containers );
final List expectedContainers =
new ArrayList(Arrays.asList(C6, C1, C2, C3, C4, C5, C7));
assertEquals( expectedContainers , containers );
}
@Test
public void testSortContainersCase6() {
final Container C1 = new Container(1);
final Container C2 = new Container(2);
final Container C3 = new Container(3);
final Container C4 = new Container(4);
final Container C5 = new Container(5);
final Container C6 = new Container(6);
final Container C7 = new Container(7);
C6.setBelowMe(C1);
C1.setAboveMe(C6);
C7.setBelowMe(C5);
C5.setAboveMe(C7);
final List containers = new ArrayList(Arrays.asList(C2, C1, C6, C7, C5, C4, C3));
SortContainers.doSort( containers );
final List expectedContainers = new ArrayList(Arrays.asList(C6, C1, C2, C3, C4, C7, C5));
assertEquals( expectedContainers , containers );
}
@Test
public void testSortContainersCase7() {
final Container C1 = new Container(1);
final Container C2 = new Container(2);
final Container C3 = new Container(3);
final Container C4 = new Container(4);
final Container C5 = new Container(5);
final Container C6 = new Container(6);
final Container C7 = new Container(7);
C1.setBelowMe(C4);
C4.setAboveMe(C1);
C2.setBelowMe(C5);
C5.setAboveMe(C2);
C3.setBelowMe(C6);
C6.setAboveMe(C3);
final List containers =
new ArrayList(Arrays.asList(C2, C1, C6, C7, C5, C4, C3));
SortContainers.doSort( containers );
final List expectedContainers =
new ArrayList(Arrays.asList(C1, C4, C2, C5, C3, C6, C7));
assertEquals( expectedContainers , containers );
}
}