/* Glazed Lists (c) 2003-2006 */
/* http://publicobject.com/glazedlists/ publicobject.com,*/
/* O'Dell Engineering Ltd.*/
package ca.odell.glazedlists;
// for being a JUnit test case
import ca.odell.glazedlists.impl.filter.StringLengthComparator;
import ca.odell.glazedlists.impl.testing.GlazedListsTests;
import ca.odell.glazedlists.impl.testing.ListConsistencyListener;
import junit.framework.TestCase;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Random;
/**
* This test verifies that the SortedList works.
*
* @author <a href="mailto:jesse@swank.ca">Jesse Wilson</a>
*/
public class SortedListTest extends TestCase {
/** the source list */
private BasicEventList<Comparable> unsortedList = null;
/** the sorted list */
private SortedList<Comparable> sortedList = null;
/** for randomly choosing list indices */
private Random random = new Random(2);
/**
* Prepare for the test.
*/
public void setUp() {
unsortedList = new BasicEventList<Comparable>();
sortedList = SortedList.create(unsortedList);
}
/**
* Clean up after the test.
*/
public void tearDown() {
unsortedList = null;
sortedList = null;
}
/**
* Tests that elements are properly moved when value changes require that
* if sort order is not enforced on the list.
*/
public void testSimpleMovesSortNotEnforced() {
unsortedList = new BasicEventList<Comparable>();
sortedList = SortedList.create(unsortedList);
sortedList.setMode(SortedList.AVOID_MOVING_ELEMENTS);
ListConsistencyListener.install(sortedList);
unsortedList.addAll(GlazedListsTests.stringToList("ABCDEFG"));
assertEquals(GlazedListsTests.stringToList("ABCDEFG"), unsortedList);
assertEquals(GlazedListsTests.stringToList("ABCDEFG"), sortedList);
unsortedList.set(3, "H");
assertEquals(GlazedListsTests.stringToList("ABCHEFG"), unsortedList);
assertEquals(GlazedListsTests.stringToList("ABCHEFG"), sortedList);
unsortedList.addAll(3, GlazedListsTests.stringToList("IJKLMNO"));
assertEquals(GlazedListsTests.stringToList("ABCIJKLMNOHEFG"), unsortedList);
assertEquals(GlazedListsTests.stringToList("ABCHEFGIJKLMNO"), sortedList);
unsortedList.removeAll(GlazedListsTests.stringToList("AEIO"));
assertEquals(GlazedListsTests.stringToList("BCJKLMNHFG"), unsortedList);
assertEquals(GlazedListsTests.stringToList("BCHFGJKLMN"), sortedList);
unsortedList.addAll(8, GlazedListsTests.stringToList("AEIO"));
assertEquals(GlazedListsTests.stringToList("BCJKLMNHAEIOFG"), unsortedList);
assertEquals(GlazedListsTests.stringToList("ABCEHFGIJKLMNO"), sortedList);
unsortedList.set(0, "Z");
assertEquals(GlazedListsTests.stringToList("ZCJKLMNHAEIOFG"), unsortedList);
assertEquals(GlazedListsTests.stringToList("AZCEHFGIJKLMNO"), sortedList);
unsortedList.set(7, "F");
assertEquals(GlazedListsTests.stringToList("ZCJKLMNFAEIOFG"), unsortedList);
assertEquals(GlazedListsTests.stringToList("AZCEFFGIJKLMNO"), sortedList);
unsortedList.addAll(0, GlazedListsTests.stringToList("EEFF"));
assertEquals(GlazedListsTests.stringToList("EEFFZCJKLMNFAEIOFG"), unsortedList);
assertEquals(GlazedListsTests.stringToList("AZCEEEFFFFGIJKLMNO"), sortedList);
unsortedList.addAll(5, GlazedListsTests.stringToList("WXYZ"));
assertEquals(GlazedListsTests.stringToList("EEFFZWXYZCJKLMNFAEIOFG"), unsortedList);
assertEquals(GlazedListsTests.stringToList("AZCEEEFFFFGIJKLMNOWXYZ"), sortedList);
sortedList.set(1, "B");
assertEquals(GlazedListsTests.stringToList("EEFFBWXYZCJKLMNFAEIOFG"), unsortedList);
assertEquals(GlazedListsTests.stringToList("ABCEEEFFFFGIJKLMNOWXYZ"), sortedList);
sortedList.clear();
assertEquals(Collections.EMPTY_LIST, unsortedList);
assertEquals(Collections.EMPTY_LIST, sortedList);
sortedList.addAll(GlazedListsTests.stringToList("ABC"));
assertEquals(GlazedListsTests.stringToList("ABC"), unsortedList);
sortedList.set(0, "C");
sortedList.set(2, "A");
assertEquals(GlazedListsTests.stringToList("CBA"), sortedList);
sortedList.add("A");
assertEquals(GlazedListsTests.stringToList("ACBA"), sortedList);
sortedList.add("C");
assertEquals(GlazedListsTests.stringToList("ACBCA"), sortedList);
}
/**
* Tests that elements are properly moved when value changes require that.
*/
public void testSimpleMoves() {
unsortedList = new BasicEventList<Comparable>();
sortedList = SortedList.create(unsortedList);
ListConsistencyListener.install(sortedList);
unsortedList.addAll(GlazedListsTests.stringToList("ABCDEFG"));
assertEquals(GlazedListsTests.stringToList("ABCDEFG"), unsortedList);
assertEquals(GlazedListsTests.stringToList("ABCDEFG"), sortedList);
unsortedList.set(3, "H");
assertEquals(GlazedListsTests.stringToList("ABCHEFG"), unsortedList);
assertEquals(GlazedListsTests.stringToList("ABCEFGH"), sortedList);
}
/**
* Test that updates, inserts and deletes all in one even are handled succesfully.
*/
public void testComplexEvents() {
unsortedList = new BasicEventList<Comparable>();
TransactionList<Comparable> nestableList = new TransactionList<Comparable>(unsortedList);
sortedList = SortedList.create(nestableList);
ListConsistencyListener.install(sortedList);
nestableList.beginEvent();
nestableList.addAll(GlazedListsTests.stringToList("ABCDEFG"));
nestableList.commitEvent();
assertEquals(GlazedListsTests.stringToList("ABCDEFG"), nestableList);
assertEquals(GlazedListsTests.stringToList("ABCDEFG"), sortedList);
nestableList.beginEvent(false);
nestableList.set(3, "H"); // ABCHEFG
nestableList.add(0, "A"); // AABCHEFG
nestableList.commitEvent();
assertEquals(GlazedListsTests.stringToList("AABCHEFG"), nestableList);
assertEquals(GlazedListsTests.stringToList("AABCEFGH"), sortedList);
nestableList.beginEvent(false);
nestableList.add(0, "I"); // IAABCHEFG
nestableList.add(1, "A"); // IAAABCHEFG
nestableList.set(5, "J"); // IAAABJHEFG
nestableList.set(9, "K"); // IAAABJHEFK
nestableList.commitEvent();
assertEquals(GlazedListsTests.stringToList("IAAABJHEFK"), nestableList);
assertEquals(GlazedListsTests.stringToList("AAABEFHIJK"), sortedList);
}
/**
* Test that the indexOf() and lastIndexOf() methods work if the SortedList
* is not actually sorted.
*
* @see <a href="https://glazedlists.dev.java.net/issues/show_bug.cgi?id=170">Bug 170</a>
*/
public void testIndexOfUnsorted() {
sortedList.setComparator(null);
sortedList.add("Riders");
sortedList.add("Stampeders");
sortedList.add("Bombers");
sortedList.add("Eskimos");
sortedList.add("Argos");
sortedList.add("Ti-Cats");
sortedList.add("Riders");
sortedList.add("Als");
assertEquals(0, sortedList.indexOf("Riders"));
assertEquals(6, sortedList.lastIndexOf("Riders"));
assertEquals(8, sortedList.indexOfSimulated("Riders"));
}
/**
* Test to verify that the sorted list is working correctly when it is
* applied to a list that already has values.
*/
public void testSortBeforeAndAfter() {
// populate a list with strings
for(int i = 0; i < 4000; i++) {
unsortedList.add(new Integer(random.nextInt()));
}
// build a control list of the desired results
final List<Comparable> controlList = new ArrayList<Comparable>();
controlList.addAll(unsortedList);
Collections.sort(controlList);
// verify the lists are equal
assertEquals(controlList, sortedList);
// re-sort the list
sortedList = SortedList.create(unsortedList);
// verify the lists are equal
assertEquals(controlList, sortedList);
}
/**
* Test to verify that the SortedList is working correctly when the
* list is changing by adds, removes and deletes.
*/
public void testSortDynamic() {
// apply various operations to the list of Integers
for(int i = 0; i < 4000; i++) {
int operation = random.nextInt(4);
int index = unsortedList.isEmpty() ? 0 : random.nextInt(unsortedList.size());
if(operation <= 1 || unsortedList.isEmpty()) {
unsortedList.add(index, new Integer(random.nextInt()));
} else if(operation == 2) {
unsortedList.remove(index);
} else if(operation == 3) {
unsortedList.set(index, new Integer(random.nextInt()));
}
}
// build a control list of the desired results
List<Comparable> controlList = new ArrayList<Comparable>();
controlList.addAll(unsortedList);
Collections.sort(controlList);
// verify the lists are equal
assertEquals(controlList, sortedList);
}
/**
* Tests to verify that the SortedList correctly handles modification.
*
* This performs a sequence of operations. Each operation is performed on
* either the sorted list or the unsorted list. The list where the operation
* is performed is selected at random.
*/
public void testSortedListWritable() {
// apply various operations to the either list
for(int i = 0; i < 4000; i++) {
List<Comparable> list;
if(random.nextBoolean()) list = sortedList;
else list = unsortedList;
int operation = random.nextInt(4);
int index = list.isEmpty() ? 0 : random.nextInt(list.size());
if(operation <= 1 || list.isEmpty()) {
list.add(index, new Integer(random.nextInt()));
} else if(operation == 2) {
list.remove(index);
} else if(operation == 3) {
list.set(index, new Integer(random.nextInt()));
}
}
// build a control list of the desired results
List<Comparable> controlList = new ArrayList<Comparable>();
controlList.addAll(unsortedList);
Collections.sort(controlList);
// verify the lists are equal
assertEquals(controlList, sortedList);
}
/**
* Tests that sorting works on a large set of filter changes.
*/
public void testAgressiveFiltering() {
BasicEventList<Object> source = new BasicEventList<Object>();
IntegerArrayMatcherEditor matcherEditor = new IntegerArrayMatcherEditor(0, 0);
FilterList<Object> filterList = new FilterList<Object>(source);
SortedList<Object> sorted = new SortedList<Object>(filterList, GlazedListsTests.intArrayComparator(0));
// populate a list with 1000 random arrays between 0 and 1000
for(int i = 0; i < 1000; i++) {
int value = random.nextInt(1000);
int[] array = new int[] { value, random.nextInt(2), random.nextInt(2), random.nextInt(2) };
source.add(array);
}
// try ten different filters
for(int i = 0; i < 10; i++) {
// apply the filter
int filterColumn = random.nextInt(3);
matcherEditor.setFilter(filterColumn + 1, 1);
// construct the control list
List<Object> controlList = new ArrayList<Object>();
controlList.addAll(filterList);
Collections.sort(controlList, GlazedListsTests.intArrayComparator(0));
// verify that the control and sorted list are the same
assertEquals(sorted.size(), controlList.size());
for(int j = 0; j < sorted.size(); j++) {
assertEquals(((int[])sorted.get(j))[0], ((int[])controlList.get(j))[0]);
}
}
}
/**
* Test indexOf() consistency
*/
public void testIndexOf() {
BasicEventList<Integer> source = new BasicEventList<Integer>();
// SortedList sorted = new SortedList<Integer>(source);
SortedList sorted= SortedList.create(source);
// Test containment of a 10 on an empty list
Integer ten = new Integer(10);
int emptyTest = sorted.indexOf(ten);
assertEquals(-1, emptyTest);
// Add 12 leading 1's
Integer one = new Integer(1);
for(int i = 0; i < 12; i++) {
source.add(one);
}
// Add 13 5's in the middle
Integer five = new Integer(5);
for(int i = 0; i < 13; i++) {
source.add(five);
}
// Add 10 trailing 9's
Integer nine = new Integer(9);
for(int i = 0; i < 10; i++) {
source.add(nine);
}
// Look for the index of a 1
int firstTestIndex = sorted.indexOf(one);
assertEquals(0, firstTestIndex);
// Look for the index of a 5
int secondTestIndex = sorted.indexOf(five);
assertEquals(12, secondTestIndex);
// Look for the index of a 9
int thirdTestIndex = sorted.indexOf(nine);
assertEquals(25, thirdTestIndex);
// Test containment of a 10
int fourthTest = sorted.indexOf(ten);
assertEquals(-1, fourthTest);
}
/**
* Test indexOf() consistency with a "weak" Comparator. A weak Comparator
* is one that returns 0 to indicate two object compare as equal even when
* .equals() would return false.
*/
public void testIndexOfWithWeakComparator() {
BasicEventList<Comparable> source = new BasicEventList<Comparable>();
SortedList<Comparable> sorted = new SortedList<Comparable>(source, GlazedLists.comparableComparator());
final Song enterSandman = new Song("Metallica", "Enter Sandman");
final Song masterOfPuppets = new Song("Metallica", "Master of Puppets");
final Song battery = new Song("Metallica", "Battery");
sorted.add(enterSandman);
sorted.add(masterOfPuppets);
assertEquals(0, sorted.indexOf(enterSandman));
assertEquals(1, sorted.indexOf(masterOfPuppets));
assertEquals(-1, sorted.indexOf(battery));
sorted.add(battery);
assertEquals(2, sorted.indexOf(battery));
assertEquals(-1, sorted.indexOf(null));
sorted.add(null);
assertEquals(0, sorted.indexOf(null));
}
/**
* Test lastIndexOf() consistency
*/
public void testLastIndexOf() {
BasicEventList<Integer> source = new BasicEventList<Integer>();
SortedList<Integer> sorted = SortedList.create(source);
// Test containment of a 10 on an empty list
Integer ten = new Integer(10);
int emptyTest = sorted.lastIndexOf(ten);
assertEquals(-1, emptyTest);
// Add 12 leading 1's
Integer one = new Integer(1);
for(int i = 0; i < 12; i++) {
source.add(one);
}
// Add 13 5's in the middle
Integer five = new Integer(5);
for(int i = 0; i < 13; i++) {
source.add(five);
}
// Add 10 trailing 9's
Integer nine = new Integer(9);
for(int i = 0; i < 10; i++) {
source.add(nine);
}
// Look for the index of a 1
int firstTestIndex = sorted.lastIndexOf(one);
assertEquals(11, firstTestIndex);
// Look for the index of a 5
int secondTestIndex = sorted.lastIndexOf(five);
assertEquals(24, secondTestIndex);
// Look for the index of a 9
int thirdTestIndex = sorted.lastIndexOf(nine);
assertEquals(34, thirdTestIndex);
// Test containment of a 10
int fourthTest = sorted.lastIndexOf(ten);
assertEquals(-1, fourthTest);
}
/**
* Test lastIndexOf() consistency with a "weak" Comparator. A weak Comparator
* is one that returns 0 to indicate two object compare as equal even when
* .equals() would return false.
*/
public void testLastIndexOfWithWeakComparator() {
BasicEventList<Comparable> source = new BasicEventList<Comparable>();
SortedList<Comparable> sorted = new SortedList<Comparable>(source, GlazedLists.comparableComparator());
final Song enterSandman = new Song("Metallica", "Enter Sandman");
final Song masterOfPuppets = new Song("Metallica", "Master of Puppets");
final Song battery = new Song("Metallica", "Battery");
sorted.add(enterSandman);
sorted.add(masterOfPuppets);
sorted.add(battery);
assertEquals(2, sorted.lastIndexOf(battery));
assertEquals(1, sorted.lastIndexOf(masterOfPuppets));
assertEquals(0, sorted.lastIndexOf(enterSandman));
sorted.add(enterSandman);
sorted.add(masterOfPuppets);
sorted.add(battery);
assertEquals(5, sorted.lastIndexOf(battery));
assertEquals(4, sorted.lastIndexOf(masterOfPuppets));
assertEquals(3, sorted.lastIndexOf(enterSandman));
assertEquals(-1, sorted.lastIndexOf(null));
sorted.add(null);
assertEquals(0, sorted.lastIndexOf(null));
sorted.add(null);
assertEquals(1, sorted.lastIndexOf(null));
}
/**
* Test containment accuracy
*/
public void testContains() {
BasicEventList<Comparable> source = new BasicEventList<Comparable>();
SortedList<Comparable> sorted = SortedList.create(source);
// Test containment of a 10 on an empty list
Integer ten = new Integer(10);
boolean emptyTest = sorted.contains(ten);
assertEquals(false, emptyTest);
// Add 12 leading 1's
Integer one = new Integer(1);
for(int i = 0; i < 12; i++) {
source.add(one);
}
// Add 13 5's in the middle
Integer five = new Integer(5);
for(int i = 0; i < 13; i++) {
source.add(five);
}
// Add 10 trailing 9's
Integer nine = new Integer(9);
for(int i = 0; i < 10; i++) {
source.add(nine);
}
// Test containment of a 1
boolean firstTest = sorted.contains(one);
assertEquals(true, firstTest);
// Test containment of a 5
boolean secondTest = sorted.contains(five);
assertEquals(true, secondTest);
// Test containment of a 9
boolean thirdTest = sorted.contains(nine);
assertEquals(true, thirdTest);
// Test containment of a 10
boolean fourthTest = sorted.contains(ten);
assertEquals(false, fourthTest);
}
/**
* Test contains() consistency with a "weak" Comparator. A weak Comparator
* is one that returns 0 to indicate two object compare as equal even when
* .equals() would return false.
*/
public void testContainsWithWeakComparator() {
BasicEventList<Comparable> source = new BasicEventList<Comparable>();
SortedList<Comparable> sorted = new SortedList<Comparable>(source, GlazedLists.comparableComparator());
final Song enterSandman = new Song("Metallica", "Enter Sandman");
final Song masterOfPuppets = new Song("Metallica", "Master of Puppets");
final Song battery = new Song("Metallica", "Battery");
sorted.add(enterSandman);
sorted.add(masterOfPuppets);
sorted.add(battery);
assertTrue(sorted.contains(enterSandman));
assertTrue(sorted.contains(masterOfPuppets));
assertTrue(sorted.contains(battery));
assertFalse(sorted.contains(new Song("Metallica", "One")));
assertFalse(sorted.contains(null));
sorted.add(null);
assertTrue(sorted.contains(null));
}
/**
* Test if the SortedList fires update events rather than delete/insert
* pairs.
*/
// public void testUpdateEventsFired() {
// // prepare a unique list with simple data
// UniqueList uniqueSource = new UniqueList(unsortedList, GlazedLists.reverseComparator());
// sortedList = new SortedList(uniqueSource);
// SortedSet data = new TreeSet(GlazedLists.reverseComparator());
// data.add("A");
// data.add("B");
// data.add("C");
// data.add("D");
// uniqueSource.replaceAll(data);
//
// // listen to changes on the sorted list
// ListEventCounter counter = new ListEventCounter();
// sortedList.addListEventListener(counter);
//
// // replace the data with an identical copy
// uniqueSource.replaceAll(data);
//
// // verify that only one event has occured
// assertEquals(1, counter.getEventCount());
// assertEquals(4, counter.getChangeCount(0));
// }
/**
* Test if the SortedList fires update events rather than delete/insert
* pairs, even if there are duplicate copies of the same value.
*/
// public void testUpdateEventsFiredWithDuplicates() {
// // create comparators for zero and one
// Comparator intCompareAt0 = GlazedListsTests.intArrayComparator(0);
// Comparator intCompareAt1 = GlazedListsTests.intArrayComparator(1);
//
// // prepare a unique list with simple data
// UniqueList uniqueSource = new UniqueList(new BasicEventList(), intCompareAt0);
// sortedList = new SortedList(uniqueSource, intCompareAt1);
// SortedSet data = new TreeSet(intCompareAt0);
// data.add(new int[] { 0, 0 });
// data.add(new int[] { 1, 0 });
// data.add(new int[] { 2, 0 });
// data.add(new int[] { 3, 0 });
// uniqueSource.replaceAll(data);
//
// // listen to changes on the sorted list
// ListEventCounter counter = new ListEventCounter();
// sortedList.addListEventListener(counter);
//
// // replace the data with an identical copy
// uniqueSource.replaceAll(data);
//
// // verify that only one event has occured
// assertEquals(1, counter.getEventCount());
// assertEquals(4, counter.getChangeCount(0));
// }
/**
* Tests that remove() works, removing the first instance of an element that
* equals() the specified element.
*/
public void testRemoveWithNoComparator() {
EventList<Comparable> basic = new BasicEventList<Comparable>();
SortedList<Comparable> sorted = new SortedList<Comparable>(basic, null);
basic.addAll(GlazedListsTests.stringToList("JamesLemieux"));
sorted.remove("e");
assertEquals(GlazedListsTests.stringToList("JamsLemieux"), sorted);
assertEquals(GlazedListsTests.stringToList("JamsLemieux"), basic);
sorted.remove("e");
assertEquals(GlazedListsTests.stringToList("JamsLmieux"), sorted);
assertEquals(GlazedListsTests.stringToList("JamsLmieux"), basic);
sorted.remove("e");
assertEquals(GlazedListsTests.stringToList("JamsLmiux"), sorted);
assertEquals(GlazedListsTests.stringToList("JamsLmiux"), basic);
sorted.remove("e");
assertEquals(GlazedListsTests.stringToList("JamsLmiux"), sorted);
assertEquals(GlazedListsTests.stringToList("JamsLmiux"), basic);
sorted.remove("m");
assertEquals(GlazedListsTests.stringToList("JasLmiux"), sorted);
assertEquals(GlazedListsTests.stringToList("JasLmiux"), basic);
sorted.remove("m");
assertEquals(GlazedListsTests.stringToList("JasLiux"), sorted);
assertEquals(GlazedListsTests.stringToList("JasLiux"), basic);
sorted.remove("m");
assertEquals(GlazedListsTests.stringToList("JasLiux"), sorted);
assertEquals(GlazedListsTests.stringToList("JasLiux"), basic);
}
/**
* Tests that remove() works, removing the first instance of an element that
* equals() the specified element.
*/
public void testRemoveWithWeakComparator() {
EventList<String> basic = new BasicEventList<String>();
SortedList sorted = new SortedList<String>(basic, GlazedLists.caseInsensitiveComparator());
basic.addAll(GlazedListsTests.stringToList("aAaBbBcCC"));
sorted.remove("A");
assertEquals(GlazedListsTests.stringToList("aaBbBcCC"), sorted);
assertEquals(GlazedListsTests.stringToList("aaBbBcCC"), basic);
sorted.remove("B");
assertEquals(GlazedListsTests.stringToList("aabBcCC"), sorted);
assertEquals(GlazedListsTests.stringToList("aabBcCC"), basic);
sorted.remove("C");
assertEquals(GlazedListsTests.stringToList("aabBcC"), sorted);
assertEquals(GlazedListsTests.stringToList("aabBcC"), basic);
sorted.remove("C");
assertEquals(GlazedListsTests.stringToList("aabBc"), sorted);
assertEquals(GlazedListsTests.stringToList("aabBc"), basic);
sorted.remove("a");
assertEquals(GlazedListsTests.stringToList("abBc"), sorted);
assertEquals(GlazedListsTests.stringToList("abBc"), basic);
sorted.remove("d");
assertEquals(GlazedListsTests.stringToList("abBc"), sorted);
assertEquals(GlazedListsTests.stringToList("abBc"), basic);
sorted.remove("B");
assertEquals(GlazedListsTests.stringToList("abc"), sorted);
assertEquals(GlazedListsTests.stringToList("abc"), basic);
sorted.remove("B");
assertEquals(GlazedListsTests.stringToList("abc"), sorted);
assertEquals(GlazedListsTests.stringToList("abc"), basic);
sorted.remove("A");
assertEquals(GlazedListsTests.stringToList("abc"), sorted);
assertEquals(GlazedListsTests.stringToList("abc"), basic);
sorted.remove("C");
assertEquals(GlazedListsTests.stringToList("abc"), sorted);
assertEquals(GlazedListsTests.stringToList("abc"), basic);
sorted.remove("a");
assertEquals(GlazedListsTests.stringToList("bc"), sorted);
assertEquals(GlazedListsTests.stringToList("bc"), basic);
sorted.remove("c");
assertEquals(GlazedListsTests.stringToList("b"), sorted);
assertEquals(GlazedListsTests.stringToList("b"), basic);
sorted.remove("c");
assertEquals(GlazedListsTests.stringToList("b"), sorted);
assertEquals(GlazedListsTests.stringToList("b"), basic);
sorted.remove("B");
assertEquals(GlazedListsTests.stringToList("b"), sorted);
assertEquals(GlazedListsTests.stringToList("b"), basic);
sorted.remove("b");
assertEquals(GlazedListsTests.stringToList(""), sorted);
assertEquals(GlazedListsTests.stringToList(""), basic);
sorted.remove("b");
assertEquals(GlazedListsTests.stringToList(""), sorted);
assertEquals(GlazedListsTests.stringToList(""), basic);
}
/**
* Tests that remove() works, removing the first instance of an element that
* equals() the specified element.
*/
public void testRemoveWithComparator() {
EventList<Comparable> basic = new BasicEventList<Comparable>();
SortedList sorted = new SortedList<Comparable>(basic, GlazedLists.comparableComparator());
basic.addAll(GlazedListsTests.stringToList("ABBCaabcc"));
sorted.remove("a");
assertEquals(GlazedListsTests.stringToList("ABBCabcc"), basic);
assertEquals(GlazedListsTests.stringToList("ABBCabcc"), sorted);
sorted.remove("B");
assertEquals(GlazedListsTests.stringToList("ABCabcc"), basic);
assertEquals(GlazedListsTests.stringToList("ABCabcc"), sorted);
sorted.remove("c");
assertEquals(GlazedListsTests.stringToList("ABCabc"), basic);
assertEquals(GlazedListsTests.stringToList("ABCabc"), sorted);
sorted.remove("d");
assertEquals(GlazedListsTests.stringToList("ABCabc"), basic);
assertEquals(GlazedListsTests.stringToList("ABCabc"), sorted);
sorted.remove("C");
assertEquals(GlazedListsTests.stringToList("ABabc"), basic);
assertEquals(GlazedListsTests.stringToList("ABabc"), sorted);
sorted.remove("B");
assertEquals(GlazedListsTests.stringToList("Aabc"), basic);
assertEquals(GlazedListsTests.stringToList("Aabc"), sorted);
sorted.remove("b");
assertEquals(GlazedListsTests.stringToList("Aac"), basic);
assertEquals(GlazedListsTests.stringToList("Aac"), sorted);
sorted.remove("A");
assertEquals(GlazedListsTests.stringToList("ac"), basic);
assertEquals(GlazedListsTests.stringToList("ac"), sorted);
sorted.remove("a");
assertEquals(GlazedListsTests.stringToList("c"), basic);
assertEquals(GlazedListsTests.stringToList("c"), sorted);
sorted.remove("a");
assertEquals(GlazedListsTests.stringToList("c"), basic);
assertEquals(GlazedListsTests.stringToList("c"), sorted);
sorted.remove("c");
assertEquals(GlazedListsTests.stringToList(""), basic);
assertEquals(GlazedListsTests.stringToList(""), sorted);
}
/**
* Test if the SortedList fires update events rather than delete/insert
* pairs, when using a ReverseComparator.
*
* <p>The source list uses a totally different comparator than the sorted list
* in order to guarantee the indices have no pattern.
*/
// public void testUpdateEventsFiredRigorous() {
// // prepare a unique list with simple data
// Comparator uniqueComparator = new ReverseStringComparator();
// UniqueList uniqueSource = new UniqueList(unsortedList, uniqueComparator);
// sortedList = new SortedList(uniqueSource);
//
// // populate a unique source with some random elements
// for(int i = 0; i < 500; i++) {
// uniqueSource.add("" + random.nextInt(200));
// }
//
// // populate a replacement set with some more random elements
// SortedSet data = new TreeSet(uniqueComparator);
// for(int i = 0; i < 500; i++) {
// data.add("" + random.nextInt(200));
// }
//
// // calculate the number of changes expected
// List intersection = new ArrayList();
// intersection.addAll(uniqueSource);
// intersection.retainAll(data);
// int expectedUpdateCount = intersection.size();
// int expectedDeleteCount = uniqueSource.size() - expectedUpdateCount;
// int expectedInsertCount = data.size() - expectedUpdateCount;
// int expectedChangeCount = expectedUpdateCount + expectedDeleteCount + expectedInsertCount;
//
// // count the number of changes performed
// ListEventCounter uniqueCounter = new ListEventCounter();
// uniqueSource.addListEventListener(uniqueCounter);
// ListEventCounter sortedCounter = new ListEventCounter();
// sortedList.addListEventListener(sortedCounter);
// //sortedList.debug = true;
//
// // perform the change
// uniqueSource.addListEventListener(new ListConsistencyListener(uniqueSource, "unique", false));
// sortedList.addListEventListener(new ListConsistencyListener(sortedList, "sorted", false));
// uniqueSource.replaceAll(data);
//
// // verify our guess on the change count is correct
// assertEquals(1, uniqueCounter.getEventCount());
// assertEquals(1, sortedCounter.getEventCount());
// assertEquals(expectedChangeCount, uniqueCounter.getChangeCount(0));
// assertEquals(expectedChangeCount, sortedCounter.getChangeCount(0));
// }
/**
* Tests that the SortedList can handle reordering events.
*/
public void testReorder() {
// prepare a source list
SortedList<String> source = SortedList.create(new BasicEventList<String>());
source.add("CB");
source.add("BC");
source.add("DD");
source.add("AA");
// create a sorted view of that list
SortedList<String> sorted = new SortedList<String>(source, GlazedLists.reverseComparator());
// create a consistency test
List<String> consistencyTestList = new ArrayList<String>();
consistencyTestList.addAll(sorted);
// change the source, this should not impact its listener
source.setComparator(new ReverseStringComparator());
assertEquals(consistencyTestList, sorted);
// change the source, this should not impact its listener
source.setComparator(null);
assertEquals(consistencyTestList, sorted);
}
/**
* Verify that the sorted list works with no compatator.
*/
public void testNoComparator() {
List<String> consistencyTestList = new ArrayList<String>();
consistencyTestList.add("A");
consistencyTestList.add("C");
consistencyTestList.add("B");
SortedList<String> sorted = new SortedList<String>(new BasicEventList<String>(), null);
sorted.addAll(consistencyTestList);
assertEquals(consistencyTestList, sorted);
sorted.set(2, "A");
sorted.clear();
assertEquals(Collections.EMPTY_LIST, sorted);
}
/**
* Test that values that are indistinguishable by the SortedList are ordered
* by their index.
*/
public void testEqualValuesOrderedByIndex() {
// create a sorted list that cannot distinguish between the data items
Comparator<String> intCompareAt0 = GlazedLists.reverseComparator(new StringLengthComparator());
sortedList.dispose();
sortedList = new SortedList(unsortedList, intCompareAt0);
// populate the unsorted list
unsortedList.add(0, "chaos"); // c
unsortedList.add(1, "fiery"); // c f
unsortedList.add(2, "gecko"); // c f g
unsortedList.add(0, "banjo"); // b c f g
unsortedList.add(2, "dingo"); // b c d f g
unsortedList.add(5, "hippo"); // b c d f g h
unsortedList.add(0, "album"); // a b c d f g h
unsortedList.add(4, "eerie"); // a b c d e f g h
assertEquals(unsortedList, sortedList);
}
/**
* Test that the SortedList doesn't get grumpy if everything is always equal.
*/
public void testAlwaysEqualComparator() {
Comparator alwaysEqualComparator = new AlwaysEqualComparator();
sortedList.dispose();
unsortedList.add(new Integer(4));
unsortedList.add(new Integer(3));
unsortedList.add(new Integer(1));
sortedList = new SortedList(unsortedList, alwaysEqualComparator);
unsortedList.add(new Integer(5));
unsortedList.add(new Integer(3));
unsortedList.add(new Integer(0));
unsortedList.add(new Integer(9));
assertEquals(unsortedList, sortedList);
}
/**
* Test that the SortedList doesn't get grumpy if half the elements are null.
*/
public void testHalfNullComparator() {
Comparator halfNullComparator = new HalfNullComparator();
sortedList.dispose();
Position p = new Position(4);
unsortedList.add(p);
unsortedList.add(new Position(3));
unsortedList.add(new Position(1));
sortedList = new SortedList(unsortedList, halfNullComparator);
p.setPosition(2);
sortedList.set(2, p);
assertEquals(unsortedList, sortedList);
}
/**
* Tests an empty sorted list's iterator
*/
public void testIteratorOnEmptySortedList() {
Iterator i = sortedList.iterator();
// validate hasNext()
assertEquals(false, i.hasNext());
// validate next() fires the correct exception
try {
i.next();
fail("An expected Exception was not thrown.");
} catch(NoSuchElementException e) {
// test passes
} catch(Exception e) {
fail("The following Exception was not expected:\n" + e);
}
// validate remove() fires the correct exception
i = sortedList.iterator();
try {
i.next();
fail("An expected Exception was not thrown.");
} catch(NoSuchElementException e) {
// test passes
} catch(Exception e) {
fail("The following Exception was not expected:\n" + e);
}
}
/**
* Tests a SortedList's iterator, read-only
*/
public void testIteratorReadOnly() {
sortedList.add("Riders");
sortedList.add("Stampeders");
sortedList.add("Bombers");
sortedList.add("Eskimos");
sortedList.add("Argos");
sortedList.add("Ti-Cats");
sortedList.add("Renegades");
sortedList.add("Als");
String[] expected = {"Als", "Argos", "Bombers", "Eskimos", "Renegades", "Riders", "Stampeders", "Ti-Cats"};
int counter = 0;
for(Iterator i = sortedList.iterator(); i.hasNext(); counter++) {
assertEquals(expected[counter], i.next());
}
assertEquals(expected.length, counter);
}
/**
* Tests a SortedList's iterator while removing
*/
public void testIteratorRemoves() {
sortedList.add("Riders");
sortedList.add("Stampeders");
sortedList.add("Bombers");
sortedList.add("Eskimos");
sortedList.add("Argos");
sortedList.add("Ti-Cats");
sortedList.add("Renegades");
sortedList.add("Als");
String[] expected = {"Als", "Argos", "Bombers", "Eskimos", "Renegades", "Riders", "Stampeders", "Ti-Cats"};
// validate remove() fires the correct exception before iteration starts
Iterator i = sortedList.iterator();
try {
i.remove();
fail("An expected Exception was not thrown.");
} catch(NoSuchElementException e) {
// test passes
}
int counter = 0;
for(i = sortedList.iterator(); i.hasNext(); counter++) {
assertEquals(expected[counter], i.next());
i.remove();
try {
i.remove();
fail("An expected Exception was not thrown.");
} catch(NoSuchElementException e) {
// test passes
}
}
assertEquals(expected.length, counter);
assertEquals(0, sortedList.size());
// validate remove() fires the correct exception after all values are removed
try {
i.remove();
fail("An expected Exception was not thrown.");
} catch(NoSuchElementException e) {
// test passes
}
}
public void testSortIndex() {
sortedList.addAll(GlazedListsTests.stringToList("ac"));
assertEquals(1, sortedList.sortIndex("b"));
assertEquals(1, sortedList.lastSortIndex("b"));
sortedList.clear();
sortedList.addAll(GlazedListsTests.stringToList("abbbc"));
assertEquals(1, sortedList.sortIndex("b"));
assertEquals(3, sortedList.lastSortIndex("b"));
assertEquals(0, sortedList.sortIndex("3"));
assertEquals(0, sortedList.lastSortIndex("3"));
assertEquals(5, sortedList.sortIndex("d"));
assertEquals(5, sortedList.lastSortIndex("d"));
}
public void testComparatorAndEqualsMethodDontAgree() {
sortedList.dispose();
sortedList = new SortedList(unsortedList, String.CASE_INSENSITIVE_ORDER);
sortedList.addAll(GlazedListsTests.stringToList("ac"));
assertEquals(1, sortedList.sortIndex("b"));
assertEquals(1, sortedList.lastSortIndex("b"));
assertEquals(-1, sortedList.indexOf("b"));
assertEquals(-1, sortedList.lastIndexOf("b"));
sortedList.clear();
sortedList.addAll(GlazedListsTests.stringToList("abbbc"));
assertEquals(1, sortedList.sortIndex("b"));
assertEquals(3, sortedList.lastSortIndex("b"));
assertEquals(1, sortedList.indexOf("b"));
assertEquals(3, sortedList.lastIndexOf("b"));
assertEquals(1, sortedList.sortIndex("B"));
assertEquals(3, sortedList.lastSortIndex("B"));
assertEquals(-1, sortedList.indexOf("B"));
assertEquals(-1, sortedList.lastIndexOf("B"));
}
public void testAddAtIndex() {
final EventList<String> source = new BasicEventList<String>();
final SortedList<String> sortedList = new SortedList<String>(source, String.CASE_INSENSITIVE_ORDER);
source.addAll(GlazedListsTests.stringToList("babac"));
assertEquals(GlazedListsTests.stringToList("babac"), source);
assertEquals(GlazedListsTests.stringToList("aabbc"), sortedList);
sortedList.add(2, "c");
assertEquals(GlazedListsTests.stringToList("cbabac"), source);
assertEquals(GlazedListsTests.stringToList("aabbcc"), sortedList);
sortedList.add(3, "d");
assertEquals(GlazedListsTests.stringToList("cbadbac"), source);
assertEquals(GlazedListsTests.stringToList("aabbccd"), sortedList);
sortedList.add(sortedList.size()-1, "a");
assertEquals(GlazedListsTests.stringToList("cbaadbac"), source);
assertEquals(GlazedListsTests.stringToList("aaabbccd"), sortedList);
sortedList.add(sortedList.size(), "e");
assertEquals(GlazedListsTests.stringToList("cbaadbace"), source);
assertEquals(GlazedListsTests.stringToList("aaabbccde"), sortedList);
}
/**
* This test ensures that the SortedList sorts by its own
* order, then by the order in the source list.
*/
public void testSortedListHandlesSortEvents() {
Comparator artistComparator = GlazedLists.beanPropertyComparator(Song.class, "artist", new String[0]);
Comparator songComparator = GlazedLists.beanPropertyComparator(Song.class, "song", new String[0]);
List<Comparable> expectedOrder;
sortedList.setComparator(null);
SortedList sortedAgain = new SortedList<Comparable>(sortedList, artistComparator);
ListConsistencyListener.install(sortedAgain);
unsortedList.add(new Song("Limp Bizkit", "Nookie"));
unsortedList.add(new Song("Limp Bizkit", "Eat You Alive"));
unsortedList.add(new Song("Limp Bizkit", "Rearranged"));
unsortedList.add(new Song("Limp Bizkit", "The Unquestionable Truth"));
unsortedList.add(new Song("Filter", "Welcome to the Fold"));
unsortedList.add(new Song("Filter", "Take a Picture"));
unsortedList.add(new Song("Filter", "Miss Blue"));
unsortedList.add(new Song("Slipknot", "Wait and Bleed"));
unsortedList.add(new Song("Slipknot", "Duality"));
unsortedList.add(new Song("Godsmack", "Whatever"));
unsortedList.add(new Song("Godsmack", "Running Blind"));
// sorted just by artist
expectedOrder = new ArrayList<Comparable>(unsortedList);
Collections.sort(expectedOrder, artistComparator);
assertEquals(expectedOrder, sortedAgain);
// sorted by artist, then by song
sortedList.setComparator(songComparator);
expectedOrder = new ArrayList<Comparable>(unsortedList);
Collections.sort(expectedOrder, GlazedLists.chainComparators((List)Arrays.asList(new Comparator[] { artistComparator, songComparator })));
assertEquals(expectedOrder, sortedAgain);
// sorted just by artist again
sortedList.setComparator(null);
expectedOrder = new ArrayList<Comparable>(unsortedList);
Collections.sort(expectedOrder, artistComparator);
assertEquals(expectedOrder, sortedAgain);
// change our data to be more random
unsortedList.clear();
Random dice = new Random(0);
List<String> artists = GlazedListsTests.stringToList("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
for(int a = 0; a < 200; a++) {
String randomArtist = artists.get(dice.nextInt(artists.size()));
String randomSong = artists.get(dice.nextInt(artists.size()));
unsortedList.add(new Song(randomArtist, randomSong));
}
// sorted by artist, then by song
sortedList.setComparator(songComparator);
expectedOrder = new ArrayList<Comparable>(unsortedList);
Collections.sort(expectedOrder, GlazedLists.chainComparators((List)Arrays.asList(new Comparator[] { artistComparator, songComparator })));
assertEquals(expectedOrder, sortedAgain);
// sorted just by artist again
sortedList.setComparator(null);
expectedOrder = new ArrayList<Comparable>(unsortedList);
Collections.sort(expectedOrder, artistComparator);
assertEquals(expectedOrder, sortedAgain);
}
public void testSortedSource() {
Comparator<Comparable> alphabetical = GlazedLists.comparableComparator();
Comparator<String> length = GlazedLists.reverseComparator(new StringLengthComparator());
sortedList.setComparator(null);
unsortedList.addAll(Arrays.asList(new String[] { "dddd", "aaa", "c", "bb" }));
assertEquals(Arrays.asList(new String[] { "dddd", "aaa", "c", "bb" }), sortedList);
SortedList<String> resortedList = new SortedList(sortedList, length);
ListConsistencyListener.install(resortedList);
assertEquals(Arrays.asList(new String[] { "c", "bb", "aaa", "dddd" }), resortedList);
sortedList.setComparator(alphabetical);
assertSortedEquals(sortedList, resortedList);
// now add some duplicates
unsortedList.addAll(Arrays.asList(new String[] { "c", "dddd", "aaa", "bb" }));
assertSortedEquals(sortedList, resortedList);
// now change the comparator
sortedList.setComparator(alphabetical);
assertSortedEquals(sortedList, resortedList);
}
public void testIteratorIsConsistent() {
ListConsistencyListener.install(sortedList);
unsortedList.addAll(Arrays.asList(new String[] { "d", "c", "a", "b" }));
Iterator<Comparable> iterator = sortedList.iterator();
assertEquals("a", iterator.next());
assertEquals("a", sortedList.get(0));
assertEquals("b", iterator.next());
assertEquals("b", sortedList.get(1));
assertEquals("c", iterator.next());
assertEquals("c", sortedList.get(2));
assertEquals("d", iterator.next());
assertEquals("d", sortedList.get(3));
}
/**
* This test ensures SortedList's generic arguments are correct.
* Specifically, a SortedList<E> should be able to accept any Comparator<? super E>.
* In other words:
*
* <p>SortedList<Number> can accept a Comparator<Number> or Comparator<Object>, but not
* a Comparator<Integer>.
*/
public void testCompilingWithGenerics() {
SortedList<Integer> integers = SortedList.create(new BasicEventList<Integer>());
// all of these Comparators should compile just fine
integers.setComparator(GlazedLists.comparableComparator());
integers.setComparator(new AlwaysEqualComparator());
new SortedList<Integer>(new BasicEventList<Integer>(), GlazedLists.comparableComparator());
new SortedList<Integer>(new BasicEventList<Integer>(), new AlwaysEqualComparator());
}
public void testChangingSortMode() {
SortedList<String> names = SortedList.create(new BasicEventList<String>());
names.setMode(SortedList.AVOID_MOVING_ELEMENTS);
names.add("");
names.add("");
names.add("");
names.add("");
names.set(0, "abba");
names.set(1, "foo fighters");
names.set(2, "nirvana");
names.set(3, "cardigans");
assertEquals("abba", names.get(0));
assertEquals("foo fighters", names.get(1));
assertEquals("nirvana", names.get(2));
assertEquals("cardigans", names.get(3));
names.setMode(SortedList.STRICT_SORT_ORDER);
assertEquals("abba", names.get(0));
assertEquals("cardigans", names.get(1));
assertEquals("foo fighters", names.get(2));
assertEquals("nirvana", names.get(3));
names.setMode(SortedList.AVOID_MOVING_ELEMENTS);
names.add("bob marley");
assertEquals("abba", names.get(0));
assertEquals("bob marley", names.get(1));
assertEquals("cardigans", names.get(2));
assertEquals("foo fighters", names.get(3));
assertEquals("nirvana", names.get(4));
names.set(1, "zamfir");
assertEquals("abba", names.get(0));
assertEquals("zamfir", names.get(1));
assertEquals("cardigans", names.get(2));
assertEquals("foo fighters", names.get(3));
assertEquals("nirvana", names.get(4));
}
public void testRemovedValueInListEvent() {
EventList<String> original = new BasicEventList<String>();
original.addAll(GlazedListsTests.stringToList("LIMPBIZKIT"));
SortedList<String> sorted = SortedList.create(original);
ListConsistencyListener<String> listConsistencyListener = ListConsistencyListener.install(sorted);
listConsistencyListener.setPreviousElementTracked(true);
original.removeAll(GlazedListsTests.stringToList("MI"));
assertEquals(GlazedListsTests.stringToList("BKLPTZ"), sorted);
// update in-place
original.set(1, "Q");
assertEquals(GlazedListsTests.stringToList("LQBZKT"), original);
assertEquals(GlazedListsTests.stringToList("BKLQTZ"), sorted);
// update-causing-move
original.set(2, "R");
assertEquals(GlazedListsTests.stringToList("LQRZKT"), original);
assertEquals(GlazedListsTests.stringToList("KLQRTZ"), sorted);
// update-without-move
sorted.setMode(SortedList.AVOID_MOVING_ELEMENTS);
original.set(1, "A");
assertEquals(GlazedListsTests.stringToList("LARZKT"), original);
assertEquals(GlazedListsTests.stringToList("KLARTZ"), sorted);
}
/**
* This test ensures that the SortedList sorts by its own
* order, then by the order in the source list.
*/
public void testChainedComparator() {
sortedList.setComparator(null);
Song nookie = new Song("Limp Bizkit", "Nookie");
Song eatYouAlive = new Song("Limp Bizkit", "Eat You Alive");
Song rearranged = new Song("Limp Bizkit", "Rearranged");
Song theUnquestionableTruth = new Song("Limp Bizkit", "The Unquestionable Truth");
Song welcomeToTheFold = new Song("Filter", "Welcome to the Fold");
Song takeAPicture = new Song("Filter", "Take a Picture");
Song missBlue = new Song("Filter", "Miss Blue");
unsortedList.add(nookie);
unsortedList.add(eatYouAlive);
unsortedList.add(takeAPicture);
unsortedList.add(rearranged);
unsortedList.add(missBlue);
unsortedList.add(theUnquestionableTruth);
unsortedList.add(welcomeToTheFold);
assertSame(nookie, sortedList.get(0));
assertSame(eatYouAlive, sortedList.get(1));
assertSame(takeAPicture, sortedList.get(2));
assertSame(rearranged, sortedList.get(3));
assertSame(missBlue, sortedList.get(4));
assertSame(theUnquestionableTruth, sortedList.get(5));
assertSame(welcomeToTheFold, sortedList.get(6));
Comparator songComparator = GlazedLists.beanPropertyComparator(Song.class, "artist", new String[] {"song"});
sortedList.setComparator(songComparator);
assertSame(missBlue, sortedList.get(0));
assertSame(takeAPicture, sortedList.get(1));
assertSame(welcomeToTheFold, sortedList.get(2));
assertSame(eatYouAlive, sortedList.get(3));
assertSame(nookie, sortedList.get(4));
assertSame(rearranged, sortedList.get(5));
assertSame(theUnquestionableTruth, sortedList.get(6));
}
/** test a sorted list for equality */
public void assertSortedEquals(List<Comparable> unsorted, SortedList sorted) {
// create a protective copy to muck with
unsorted = new ArrayList<Comparable>(unsorted);
if(sorted.getComparator() != null) Collections.sort(unsorted, sorted.getComparator());
assertEquals(unsorted, sorted);
}
/**
* Compares two objects to be equal.
*/
static class AlwaysEqualComparator implements Comparator<Object> {
public int compare(Object a, Object b) {
return 0;
}
}
/**
* Compares two objects with the second one always null.
*/
static class HalfNullComparator implements Comparator {
Comparator target = GlazedLists.comparableComparator();
public int compare(Object a, Object b) {
return target.compare(b, null);
}
}
/**
* Simple class that sorts in the same order as its position value. Like an
* {@link Integer}, but mutable.
*/
static class Position implements Comparable {
private int position;
public Position(int position) {
this.position = position;
}
public int getPosition() { return position; }
public void setPosition(int position) { this.position = position; }
public String toString() {
return "P:" + position;
}
public int compareTo(Object o) {
return position - ((Position)o).position;
}
}
/**
* A Comparator that compares strings from end to beginning rather than
* normally.
*/
private static class ReverseStringComparator implements Comparator<String> {
public Comparator<String> delegate = (Comparator)GlazedLists.comparableComparator();
public int compare(String a, String b) {
return delegate.compare(flip(a), flip(b));
}
public String flip(String original) {
char[] originalAsChars = original.toCharArray();
int length = originalAsChars.length;
for(int i = 0; i < (length / 2); i++) {
char temp = originalAsChars[i];
originalAsChars[i] = originalAsChars[length - i - 1];
originalAsChars[length - i - 1] = temp;
}
return new String(originalAsChars);
}
}
public static class Song implements Comparable {
String artist;
String song;
public Song(String artist, String song) {
this.artist = artist;
this.song = song;
}
public String getArtist() {
return artist;
}
public String getSong() {
return song;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final Song song1 = (Song) o;
if (!artist.equals(song1.artist)) return false;
if (!song.equals(song1.song)) return false;
return true;
}
public int hashCode() {
int result;
result = artist.hashCode();
result = 29 * result + song.hashCode();
return result;
}
public int compareTo(Object o) {
final Song song = (Song) o;
return this.getArtist().compareTo(song.getArtist());
}
public String toString() {
return this.getArtist() + " - " + this.getSong();
}
}
}