package com.levelup.java.collections;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Doubles;
import com.google.common.primitives.Ints;
/**
* This java example will demonstrate how to sort a collection
*
* @author Justin Musgrove
* @see <a
* href='http://www.leveluplunch.com/java/examples/sort-a-collection/'>Sort
* a collection</a>
*
*/
public class SortACollection {
private static final Logger logger = Logger
.getLogger(SortACollection.class);
public class Wrestler {
private String name;
private double weightClass;
private int wins;
public Wrestler(String name, double weightClass, int wins) {
super();
this.name = name;
this.weightClass = weightClass;
this.wins = wins;
}
public String getName() {
return name;
}
public double getWeightClass() {
return weightClass;
}
public int getWins() {
return wins;
}
@Override
public String toString() {
return Objects.toStringHelper(this).add("name", name)
.add("weightClass", weightClass).add("wins", wins)
.toString();
}
}
private List<Wrestler> wrestlers = Lists.newArrayList();
@Before
public void setup() {
wrestlers.add(new Wrestler("Abe", 151, 5));
wrestlers.add(new Wrestler("Steve", 151, 7));
wrestlers.add(new Wrestler("Jack", 151, 1));
wrestlers.add(new Wrestler("Jim", 215, 15));
wrestlers.add(new Wrestler("Jack", 215, 1));
wrestlers.add(new Wrestler("Joe", 215, 8));
wrestlers.add(new Wrestler("Harry", 119, 6));
wrestlers.add(new Wrestler("Sally", 119, 9));
}
/**
* Display wrestlers by weight class
*/
@Test
public void sort_collection_with_java() {
Comparator<Wrestler> byWeightClass = new Comparator<Wrestler>() {
public int compare(Wrestler left, Wrestler right) {
return Double.compare(left.getWeightClass(),
right.getWeightClass()); // use your logic
}
};
Collections.sort(wrestlers, byWeightClass);
logger.info(wrestlers);
Wrestler wrestler = wrestlers.get(0);
assertEquals(119, wrestler.weightClass, 0);
}
@Test
public void sort_collection_with_java8_byweight() {
wrestlers.sort((w1, w2) -> Double.compare(w1.getWeightClass(),
w2.getWeightClass()));
logger.info(wrestlers);
Optional<Wrestler> wrestler = wrestlers.stream().findFirst();
assertEquals(119, wrestler.get().getWeightClass(), 0);
}
@Test
public void sort_collection_with_java8_byweight_reverse() {
Comparator<Wrestler> normal = ((w1, w2) -> Double.compare(
w1.getWeightClass(), w2.getWeightClass()));
Comparator<Wrestler> reversed = normal.reversed();
wrestlers.sort(reversed);
logger.info(wrestlers);
Optional<Wrestler> wrestler = wrestlers.stream().findFirst();
assertEquals(215, wrestler.get().getWeightClass(), 0);
}
@Test
public void sort_collection_with_java8_byname() {
wrestlers.sort((w1, w2) -> w1.getName().compareTo(w2.getName()));
logger.info(wrestlers);
Optional<Wrestler> wrestler = wrestlers.stream().findFirst();
assertEquals("Abe", wrestler.get().getName());
}
@Test
public void sort_collection_with_java8_byweight_wins() {
List<Wrestler> sorted = wrestlers
.stream()
.sorted((w1, w2) -> Double.compare(w1.getWeightClass(),
w2.getWeightClass()))
.sorted((w1, w2) -> Integer.compare(w1.getWins(), w2.getWins()))
.collect(Collectors.toList());
logger.info(sorted);
Optional<Wrestler> wrestler = sorted.stream().findFirst();
assertEquals(151, wrestler.get().getWeightClass(), 0);
}
static final Ordering<Wrestler> byWeightClass = new Ordering<Wrestler>() {
public int compare(Wrestler left, Wrestler right) {
return Doubles.compare(left.getWeightClass(),
right.getWeightClass());
}
};
static final Ordering<Wrestler> byName = new Ordering<Wrestler>() {
public int compare(Wrestler left, Wrestler right) {
return left.getName().equals(right.getName()) ? 1 : 0;
}
};
static final Ordering<Wrestler> byWins = new Ordering<Wrestler>() {
public int compare(Wrestler left, Wrestler right) {
return Ints.compare(left.getWins(), right.getWins());
}
};
/**
* Display wrestlers by weight class
*/
@Test
public void sort_collection_with_guava() {
Collections.sort(wrestlers, byWeightClass);
logger.info(wrestlers);
Wrestler aWrestlerWithLowestWeight = Iterables
.getFirst(wrestlers, null);
assertNotNull(aWrestlerWithLowestWeight);
assertEquals(119, aWrestlerWithLowestWeight.getWeightClass(), 0);
}
/**
* Display a wrestlers by name and show weight class
*/
@Test
public void display_wrestlers_by_weightclass_and_in_alphabetical_order() {
Collections.sort(wrestlers, byName);
logger.info(wrestlers);
Wrestler firstAlphabetically = Iterables.getFirst(wrestlers, null);
assertNotNull(firstAlphabetically);
assertEquals("Abe", firstAlphabetically.getName());
}
/**
* Display wrestlers from highest weight class to lowest
*/
@Test
public void sort_collection_in_reverse_with_guava() {
Collections.sort(wrestlers, byWeightClass.reverse());
logger.info(wrestlers);
Wrestler aWrestlerWithHighestWeightClass = Iterables.getFirst(
wrestlers, null);
assertNotNull(aWrestlerWithHighestWeightClass);
assertEquals(215, aWrestlerWithHighestWeightClass.getWeightClass(), 0);
}
/**
* display a list of wrestlers by order of weight class and wins
*/
@Test
public void sort_collection_with_multiple_comparables_guava() {
Collections.sort(wrestlers, byWeightClass.compound(byWins));
logger.info(wrestlers);
Wrestler aLowestWeightClassWrestler = Iterables.getFirst(wrestlers,
null);
assertNotNull(aLowestWeightClassWrestler);
assertEquals(119, aLowestWeightClassWrestler.getWeightClass(), 0);
}
/**
* Display top wrestlers in each weight class
*/
@Test
public void sort_collection_with_multiple_comparables_guava_getfirstElement() {
// first order elements
Collections.sort(wrestlers, byWeightClass.compound(byWins.reverse()));
// next get the first wrestler in each weight class which should have
// the most wins
ImmutableListMultimap<Double, Wrestler> wrestlersMappedByWeightClass = Multimaps
.index(wrestlers, new Function<Wrestler, Double>() {
public Double apply(Wrestler from) {
return new Double(from.getWeightClass());
}
});
logger.info(wrestlersMappedByWeightClass);
// for each weight class get the first element which should be wrestler
// with most wins
for (Double weightClass : wrestlersMappedByWeightClass.keySet()) {
List<Wrestler> weightClassWrestlers = wrestlersMappedByWeightClass
.get(weightClass);
logger.info(weightClass + " - "
+ Iterables.getFirst(weightClassWrestlers, null));
}
}
}