import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Vector; import net.sf.jga.fn.BinaryFunctor; import net.sf.jga.fn.Generator; import net.sf.jga.fn.UnaryFunctor; import net.sf.jga.fn.adaptor.ConstantBinary; import net.sf.jga.fn.adaptor.GenerateBinary; import net.sf.jga.fn.adaptor.Random; import net.sf.jga.fn.comparison.EqualTo; import net.sf.jga.fn.comparison.LessEqual; import net.sf.jga.fn.logical.UnaryNegate; import net.sf.jga.fn.property.CompareProperty; import net.sf.jga.fn.property.GetProperty; import net.sf.jga.util.CachingIterator; import net.sf.jga.util.FindIterator; import net.sf.jga.util.GenericComparator; import net.sf.jga.util.LookAheadIterator; import static net.sf.jga.util.Iterables.*; public class Fruit { public Fruit(String name, PlantType type) { this.name = name; this.type = type; } // - - - - - - - - - // Name property // - - - - - - - - - private String name; /** * Get the Name value. * @return the Name value. */ public String getName() { return name; } /** * Set the Name value. * @param newName The new Name value. */ public void setName(String newName) { this.name = newName; } // - - - - - - - - - // Type property // - - - - - - - - - public enum PlantType { tree, vine, bush }; private PlantType type; /** * Get the Type value. * @return the Type value. */ public PlantType getType() { return type; } /** * Set the Type value. * @param newType The new Type value. */ public void setType(PlantType newType) { this.type = newType; } public String toString() { return getName(); } // - - - - - - - - - // Fruit Comparator // - - - - - - - - - static public Comparator comp = new GenericComparator(new GetProperty(Fruit.class, "Name")); // A few example fruit objects static public final Fruit APPLE = new Fruit("apple", PlantType.tree); static public final Fruit BANANA = new Fruit("banana", PlantType.tree); static public final Fruit BLACKBERRY = new Fruit("blackberry", PlantType.bush); static public final Fruit BLUEBERRY = new Fruit("blueberry", PlantType.bush); static public final Fruit CHERRY = new Fruit("cherry", PlantType.tree); static public final Fruit GRAPE = new Fruit("grape", PlantType.vine); static public final Fruit GRAPEFRUIT = new Fruit("grapefruit", PlantType.tree); static public final Fruit LEMON = new Fruit("lemon", PlantType.tree); static public final Fruit LIME = new Fruit("lime", PlantType.tree); static public final Fruit MANGO = new Fruit("mango", PlantType.tree); static public final Fruit ORANGE = new Fruit("orange", PlantType.tree); static public final Fruit PEAR = new Fruit("pear", PlantType.tree); static public final Fruit STRAWBERRY = new Fruit("strawberry", PlantType.bush); static public final Fruit TOMATO = new Fruit("tomato", PlantType.bush); static public final Fruit WATERMELON = new Fruit("watermelon", PlantType.vine); // a few equivalent items static public final Fruit GRANNY_SMITH = new Fruit("apple", PlantType.tree); static public final Fruit BARTLETT = new Fruit("pear", PlantType.tree); static public final Fruit ANJOU = new Fruit("pear", PlantType.tree); static public final Fruit VALENCIA = new Fruit("orange", PlantType.tree); static public final Fruit KEYLIME = new Fruit("lime", PlantType.tree); // the main alphabetic list of fruts static public final List fruits = Arrays.asList( APPLE, BANANA, BLACKBERRY, BLUEBERRY, CHERRY, GRAPE, GRAPEFRUIT, LEMON, LIME, MANGO, ORANGE, PEAR, STRAWBERRY, TOMATO, WATERMELON); // the same list of fruits, ordered by type of fruit static public final List fruitsByType = Arrays.asList( APPLE, BANANA, CHERRY, GRAPEFRUIT, LEMON, LIME, MANGO, ORANGE, PEAR, BLACKBERRY, BLUEBERRY, STRAWBERRY, TOMATO, GRAPE, WATERMELON); // a smaller list with duplicate entries static public final List citrus = Arrays.asList( GRAPEFRUIT, LEMON, LEMON, LEMON, LIME, LIME, ORANGE, ORANGE ); // another list with equivalent entries static public final List dupfruits = Arrays.asList( APPLE, GRANNY_SMITH, ORANGE, VALENCIA, PEAR, ANJOU, BARTLETT, LIME, KEYLIME); // a short list of yellow fruis static public final List yellow = Arrays.asList(BANANA, LEMON, PEAR); static public void main(String[] args) { // ============================== // Use a functor as a list filter // ============================== UnaryFunctor growsOnTree = new CompareProperty(Fruit.class,"Type",PlantType.tree); System.out.println(); System.out.println("Grows on Trees"); System.out.println("=============="); for(Fruit f : filter(fruits, growsOnTree)) { System.out.println(f); } // The same idea, just with a different filter UnaryFunctor noTreeFruits = new UnaryNegate(growsOnTree); System.out.println(); System.out.println("Don't grow on Trees"); System.out.println("==================="); for(Fruit f : filter(fruits, noTreeFruits)) { System.out.println(f); } // ============================== // Remove adjacent duplicates // ============================== System.out.println(); System.out.println("Unique Citrus"); System.out.println("============="); for(Fruit f : unique(citrus)) { System.out.println(f); } // another form of unique() takes a functor to compare // adjacent entries. BinaryFunctor sameKind = new EqualTo(Fruit.comp); System.out.println(); System.out.println("Unique Kinds"); System.out.println("============"); for(Fruit f : unique(dupfruits, sameKind)) { System.out.println(f); } // ============================== // Transform entries in a list // ============================== UnaryFunctor getType = new GetProperty(Fruit.class,"Type"); System.out.println(); System.out.println("Fruit Types"); System.out.println("============"); for(PlantType f : transform(fruitsByType, getType)) { System.out.println(f); } // remove the duplicate types System.out.println(); System.out.println("Unique Types"); System.out.println("============"); for(PlantType f : unique(transform(fruitsByType, getType))) { System.out.println(f); } // ============================== // Merge multiple lists // ============================== System.out.println(); System.out.println("Merged Yellow & Citrus Fruits"); System.out.println("============================="); for(Fruit f : merge(yellow, citrus, Fruit.comp)) { System.out.println(f); } // remove duplicates in the merged list System.out.println(); System.out.println("Merged Yellow & Citrus, no dupes"); System.out.println("================================"); for(Fruit f : unique(merge(yellow, citrus, Fruit.comp))) { System.out.println(f); } // append the lists, rather than merge them System.out.println(); System.out.println("Appended Yellow & Citrus Fruits"); System.out.println("==============================="); for(Fruit f : merge(yellow, unique(citrus), new ConstantBinary(Boolean.TRUE))) { System.out.println(f); } // shuffle two lists, rather than merge them. first, we need a generator // that simulates fliping a coin... Generator coinflip = new LessEqual.Comparable().bind2nd(0.5d).generate(new Random()); // ... and we bind that into a GenerateBinary, which will accept and ignre // two fruit arguements BinaryFunctor shuffle = new GenerateBinary(coinflip); System.out.println(); System.out.println("Shuffled Yellow & Citrus Fruits"); System.out.println("==============================="); for(Fruit f : merge(yellow, unique(citrus), shuffle)) { System.out.println(f); } // ================================= // Look Ahead of the current postion // ================================= System.out.println(); System.out.println("Looking Ahead: Yellow fruits"); System.out.println("============================"); LookAheadIterator lai = new LookAheadIterator(yellow.iterator()); for(Fruit f : lai) { Fruit f1 = lai.hasNextPlus(1) ? lai.peek(1) : null; System.out.println(f +"\t"+f1); } // ================================= // Look behind the current postion // ================================= System.out.println(); System.out.println("Looking Behind: Yellow fruits"); System.out.println("============================="); CachingIterator ci = new CachingIterator(yellow.iterator(), 2); for(Fruit f : ci) { Fruit f1 = ci.hasCached(2) ? ci.cached(2) : null; System.out.println(f +"\t"+f1); } // ================================= // selectively skip entries // ================================= // skips all of the trees at the beginning of the alphabetic list System.out.println(); System.out.println("Skipping initial Trees"); System.out.println("======================"); FindIterator fi1 = new FindIterator(fruits.iterator()); fi1.findNext(noTreeFruits); for(Fruit f : fi1) { System.out.println(f); } // skips all but the first tree in any // sequence of trees System.out.println(); System.out.println("Finding first non-tree after every tree"); System.out.println("======================================="); FindIterator fi2 = new FindIterator(fruits.iterator()); for(Fruit f : fi2) { if (growsOnTree.fn(f)) fi2.findNext(noTreeFruits); System.out.println(f); } System.out.println(); } }