Jaggregate version 3.3

Examples of Usage

Collection

Every collection class in Jaggregate implements the Collection interface. Collection provides a read-only view of its implementers, with no particular ordering mandated for the elements. Illustrated here are the operations you can perform on a Jaggregate collection using just the Collection interface.

package jaggregate.examples; import java.io.PrintStream; import static jaggregate.Bag.*; import jaggregate.BinaryFunctor; import jaggregate.Collection; import static jaggregate.Strings.*; import jaggregate.UnaryCondition; import jaggregate.UnaryFunctor; class CollectionExample { public static void main( String[] args ) { Collection<String> littleFibs = bagWith( "zero", "one", "one", "two", "three", "five", "eight" ); System.out.println( "all even length? " + littleFibs.allSatisfy( EVEN_LENGTH ) ); System.out.println( "any even length? " + littleFibs.anySatisfy( EVEN_LENGTH ) ); Collection<Integer> lengths = littleFibs.collect( LENGTH ); System.out.println( "here's an even length: " + lengths.detect( EVEN ) ); System.out.println( "the little fibs, in no particular order:" ); littleFibs.forEachDo( printOnLinesTo( System.out ) ); System.out.println( "is 'eleven' in the mix? " + littleFibs.includes( "eleven" ) ); System.out.println( "sum of the lengths: " + lengths.inject( 0, SUM ) ); System.out.println( "empty? " + littleFibs.isEmpty() ); System.out.println( "how many 'one's? " + littleFibs.occurrencesOf( "two" ) ); System.out.println( "odd-length fib strings: " + littleFibs.reject( EVEN_LENGTH ) ); System.out.println( "even-length fib strings: " + littleFibs.select( EVEN_LENGTH ) ); System.out.println( "how many? " + littleFibs.size() ); } private static final UnaryCondition<String> EVEN_LENGTH = new UnaryCondition<String>() { public boolean matches( String target ) { return target != null && EVEN.matches( target.length() ); } }; private static final UnaryCondition<Integer> EVEN = new UnaryCondition<Integer>() { public boolean matches( Integer target ) { return target != null && ( target & 1 ) == 0; } }; private static <A> UnaryFunctor<A, Void> printOnLinesTo( final PrintStream out ) { return new UnaryFunctor<A, Void>() { public Void evaluate( A target ) { out.println( target ); return null; } }; } private static BinaryFunctor<Integer, Integer, Integer> SUM = new BinaryFunctor<Integer, Integer, Integer>() { public Integer evaluate( Integer first, Integer second ) { return first + second; } }; }
all even length? false any even length? true here's an even length: 4 the little fibs, in no particular order: eight zero two three five one one is 'eleven' in the mix? false sum of the lengths: 27 empty? false how many 'one's? 1 odd-length fib strings: [eight,two,three,one,one] even-length fib strings: [zero,five] how many? 7
Top

ExtensibleCollection

Collections aren't much good unless they can contain elements. The interface that provides the basic protocols for adding and removing elements from collections is ExtensibleCollection. Here are the additional ExtensibleCollection operations in action:

package jaggregate.examples; import static jaggregate.Bag.*; import static jaggregate.Comparables.*; import jaggregate.ExtensibleCollection; import static jaggregate.Objects.*; class ExtensibleCollectionExample { public static void main( String[] args ) { ExtensibleCollection<Integer> fibs = bagWith( 0, 1, 1, 2, 3, 5, 8 ); fibs.add( 13 ); fibs.addAll( 21, 34, 55 ); fibs.remove( 0 ); fibs.removeAll( 2 ); fibs.removeIf( equalTo( 1 ) ); fibs.retainAll( 13, 21, 34 ); fibs.retainIf( greaterThan( 20 ) ); System.out.println( "some fibs > 20: " + fibs ); } }
some fibs > 20: [34,21]
Top

Set

A Set is an ExtensibleCollection that disallows duplicate elements. Duplicates are determined according to the elements' equals predicate. It most closely resembles a java.util.Set. In an IdentitySet, duplicates are decided by identity (==).

package jaggregate.examples; import jaggregate.IdentitySet; import jaggregate.Set; import static jaggregate.Set.*; class SetExample { public static void main( String[] args ) { Set<Integer> littlePrimes = setWith( 2, 3, 5, 7 ); System.out.println( "here are some primes: " + littlePrimes ); littlePrimes.add( 7 ); System.out.println( "after adding duplicate 7: " + littlePrimes ); IdentitySet<Integer> primesByIdentity = littlePrimes.toIdentitySet(); primesByIdentity.add( new Integer( 7 ) ); System.out.println( "adding unique 7 to identity set: " + primesByIdentity ); } }
here are some primes: [2,5,7,3] after adding duplicate 7: [2,5,7,3] adding unique 7 to identity set: [java.lang.Integer@3,java.lang.Integer@5,java.lang.Integer@2,java.lang.Integer@7,java.lang.Integer@7]
Top

Set

A Bag is an ExtensibleCollection that, unlike Set, allows duplicate elements. Duplicates are determined according to the elements' equals predicate. In an IdentityBag, duplicates are decided by identity (==).

package jaggregate.examples; import jaggregate.Bag; import static jaggregate.Bag.*; import jaggregate.IdentitySet; class BagExample { public static void main( String[] args ) { Bag<Integer> littlePrimes = bagWith( 2, 3, 5, 7 ); System.out.println( "here are some primes: " + littlePrimes ); littlePrimes.add( 7 ); System.out.println( "after adding duplicate 7: " + littlePrimes ); System.out.println( "how many 7's? " + littlePrimes.occurrencesOf( 7 ) ); littlePrimes.remove( 7 ); System.out.println( "removed one, now how many? " + littlePrimes.occurrencesOf( 7 ) ); IdentitySet<Integer> primesByIdentity = littlePrimes.toIdentitySet(); Integer seven = new Integer( 7 ); primesByIdentity.add( seven ); System.out.println( "adding unique 7 to identity set: " + primesByIdentity ); System.out.println( "how many 7's? " + littlePrimes.occurrencesOf( 7 ) ); System.out.println( "how many 'new' 7's? " + littlePrimes.occurrencesOf( seven ) ); } }
here are some primes: [2,5,7,3] after adding duplicate 7: [2,5,7,7,3] how many 7's? 2 removed one, now how many? 1 adding unique 7 to identity set: [java.lang.Integer@3,java.lang.Integer@2,java.lang.Integer@7,java.lang.Integer@7,java.lang.Integer@5] how many 7's? 1 how many 'new' 7's? 1
Top

ReadOnlySequence

A ReadOnlySequence is a Collection whose elements are stored in an order. Its elements are accessed via an integer index.

package jaggregate.examples; import java.io.PrintStream; import jaggregate.BinaryFunctor; import static jaggregate.OrderedCollection.*; import jaggregate.ReadOnlySequence; import jaggregate.UnaryCondition; import jaggregate.UnaryFunctor; import jaggregate.UnaryPredicate; class ReadOnlySequenceExample { public static void main( String[] args ) { ReadOnlySequence<Integer> fibs = orderedCollectionWith( 0, 1, 1, 2, 3, 5, 8 ); ReadOnlySequence<String> fibWords = orderedCollectionWith( "zero", "one", "one", "two", "three", "five", "eight" ); System.out.println( "the fib after 3? " + fibs.after( 3 ) ); System.out.println( "the fib at index 3? " + fibs.at( 3 ) ); System.out.println( "the fibs before 3? " + fibs.before( 3 ) ); System.out.println( "tacked on more fibs temporarily: " + fibs.concat( orderedCollectionWith( 13, 21, 34 ) ) ); System.out.println( "slice from 1 to 4? " + fibs.copyRange( 1, 4 ) ); System.out.println( "copy with 55: " + fibs.copyWith( 55 ) ); System.out.println( "copy without 3: " + fibs.copyWithout( 3 ) ); fibs.doWithIndex( printWithIndexOn( System.out ) ); fibs.doWithOthers( fibWords, new BinaryFunctor<Integer, String, Void>() { public Void evaluate( Integer first, String second ) { System.out.println( first + " = " + second ); return null; } } ); System.out.println( "index of first fib divisible by 3? " + fibs.findFirst( divisibleBy( 3 ) ) ); System.out.println( "index of last fib divisible by 5? " + fibs.findLast( divisibleBy( 5 ) ) ); System.out.println( "first fib? " + fibs.first() ); fibs.forEachInRangeDo( 1, 5, printOnLinesTo( System.out ) ); fibs.forEachInRangeDoWithIndex( 1, 5, printWithIndexOn( System.out ) ); fibs.forEachInReverseDo( printOnLinesTo( System.out ) ); System.out.println( "index of '8'? " + fibs.indexOf( 8 ) ); System.out.println( "index of {1, 2, 3}? " + fibs.indexOf( orderedCollectionWith( 1, 2, 3 ), 0 ) ); System.out.println( "last fib? " + fibs.last() ); System.out.println( "fibs in reverse: " + fibs.reverse() ); } private static <E> UnaryFunctor<E, Object> printOnLinesTo( final PrintStream sink ) { return new UnaryFunctor<E, Object>() { public Object evaluate( E target ) { sink.println( target ); return this; } }; } private static <E> BinaryFunctor<Integer, E, Void> printWithIndexOn( final PrintStream sink ) { return new BinaryFunctor<Integer, E, Void>() { public Void evaluate( Integer index, E element ) { sink.println( "element at index " + index + ": " + element ); return null; } }; } private static UnaryCondition<Integer> divisibleBy( final int divisor ) { return new UnaryCondition<Integer>() { public boolean matches( Integer target ) { return target % divisor == 0; } }; } }
the fib after 3? 5 the fib at index 3? 2 the fibs before 3? 2 tacked on more fibs temporarily: [0,1,1,2,3,5,8,13,21,34] slice from 1 to 4? [1,1,2,3] copy with 55: [0,1,1,2,3,5,8,55] copy without 3: [0,1,1,2,5,8] element at index 0: 0 element at index 1: 1 element at index 2: 1 element at index 3: 2 element at index 4: 3 element at index 5: 5 element at index 6: 8 0 = zero 1 = one 1 = one 2 = two 3 = three 5 = five 8 = eight index of first fib divisible by 3? 0 index of last fib divisible by 5? 5 first fib? 0 1 1 2 3 5 element at index 1: 1 element at index 2: 1 element at index 3: 2 element at index 4: 3 element at index 5: 5 8 5 3 2 1 1 0 index of '8'? 6 index of {1, 2, 3}? 2 last fib? 8 fibs in reverse: [8,5,3,2,1,1,0]
Top

Interval

An Interval is a ReadOnlySequence of numbers which form an arithmetic progression. All the derivatives of java.lang.Number in JDK 5 which override equals() for value-based equality are supported as type arguments for Intervals.

package jaggregate.examples; import java.io.PrintStream; import static jaggregate.Interval.*; import jaggregate.ReadOnlySequence; import jaggregate.UnaryFunctor; class IntervalExample { public static void main( String[] args ) { ReadOnlySequence<Integer> singleDigits = fromTo( 0, 9 ); singleDigits.forEachDo( printOnLinesTo( System.out ) ); ReadOnlySequence<Integer> singleDigitEvens = fromToBy( 0, 9, 2 ); singleDigitEvens.forEachDo( printOnLinesTo( System.out ) ); } private static <A> UnaryFunctor<A, Void> printOnLinesTo( final PrintStream out ) { return new UnaryFunctor<A, Void>() { public Void evaluate( A target ) { out.println( target ); return null; } }; } }
0 1 2 3 4 5 6 7 8 9 0 2 4 6 8
Top

Sequence

A Sequence comprises the capabilities of a ReadOnlySequence and the ability to replace elements in the sequence.

package jaggregate.examples; import static jaggregate.Arrays.*; import static jaggregate.OrderedCollection.*; import jaggregate.Sequence; class SequenceExample { public static void main( String[] args ) { Sequence<String> animalNames = orderedCollectionWith( "kinkajou", "okapi", "oryx" ); System.out.println( "here are some animal names: " + animalNames ); animalNames.putAt( 0, "wallaby" ); System.out.println( "after first one put: " + animalNames ); animalNames.putAtAll( arrayWith( 1, 2 ), "koala" ); System.out.println( "after last two put: " + animalNames ); animalNames.putAtAll( "puma" ); System.out.println( "after put-at-all: " + animalNames ); animalNames.replace( 0, 1, "antelope" ); System.out.println( "first two replaced: " + animalNames ); animalNames.replaceRange( 1, 2, orderedCollectionWith( "lemur", "python" ) ); System.out.println( "last two replaced with sequence: " + animalNames ); animalNames.replaceRange( 0, 1, orderedCollectionWith( "camel", "llama", "chimpanzee" ), 1 ); System.out.println( "last two replaced with sequence at offset: " + animalNames ); } }
here are some animal names: [kinkajou,okapi,oryx] after first one put: [wallaby,okapi,oryx] after last two put: [wallaby,koala,koala] after put-at-all: [puma,puma,puma] first two replaced: [antelope,antelope,puma] last two replaced with sequence: [antelope,lemur,python] last two replaced with sequence at offset: [llama,chimpanzee,python]
Top

ContractibleSequence

A ContractibleSequence can have its elements removed.

package jaggregate.examples; import jaggregate.ContractibleSequence; import static jaggregate.OrderedCollection.*; class ContractibleSequenceExample { public static void main( String[] args ) { ContractibleSequence<String> animalNames = orderedCollectionWith( "kinkajou", "okapi", "oryx", "puma", "rorqual" ); System.out.println( "here are some animal names: " + animalNames ); animalNames.removeAt( 2 ); System.out.println( "after removing third name: " + animalNames ); animalNames.removeFirst(); System.out.println( "after removing first name: " + animalNames ); animalNames.removeLast(); System.out.println( "after removing last name: " + animalNames ); } }
here are some animal names: [kinkajou,okapi,oryx,puma,rorqual] after removing third name: [kinkajou,okapi,puma,rorqual] after removing first name: [okapi,puma,rorqual] after removing last name: [okapi,puma]
Top

OrderedCollection

As the above examples suggest, an OrderedCollection supports the ExtensibleCollection, Sequence, and ContractibleSequence protocols. It most closely resembles a java.util.ArrayList.

Top

SortedCollection

A SortedCollection supports the ExtensibleCollection, ReadOnlySequence, and ContractibleSequence protocols. It adds the additional constraint of imposing a total ordering on its elements through the use of a Comparator. NaturallySortedCollections accept elements which are already Comparable, so that the elements' natural ordering is used.

package jaggregate.examples; import java.io.Serializable; import java.util.Comparator; import jaggregate.NaturallySortedCollection; import static jaggregate.NaturallySortedCollection.*; import jaggregate.SortedCollection; import static jaggregate.SortedCollection.sortedCollectionWith; class SortedCollectionExample { public static void main( String[] args ) { SortedCollection<String> byLengthAndAlpha = sortedCollectionWith( new ByLengthAndAlpha(), "okapi", "oryx", "rorqual", "kinkajou", "puma" ); System.out.println( "by length and alpha: " + byLengthAndAlpha ); byLengthAndAlpha.add( "bear" ); System.out.println( "added a bear: " + byLengthAndAlpha ); NaturallySortedCollection<String> naturally = naturallySortedCollectionFrom( byLengthAndAlpha ); System.out.println( "by natural sort: " + naturally ); } private static class ByLengthAndAlpha implements Comparator<String>, Serializable { private static final long serialVersionUID = -1L; public int compare( String first, String second ) { if ( first.length() < second.length() ) return -1; if ( first.length() > second.length() ) return 1; return first.compareTo( second ); } } }
by length and alpha: [oryx,puma,okapi,rorqual,kinkajou] added a bear: [bear,oryx,puma,okapi,rorqual,kinkajou] by natural sort: [bear,kinkajou,okapi,oryx,puma,rorqual]
Top

Dictionary

A Dictionary is an ExtensibleCollection of Pairs, whose values can be associated with keys. It most closely resembles a java.util.Map. Key equality is determined by the keys' equals predicate. In an IdentityDictionary, just as with java.util.IdentityHashMap key equality is decided by ==.

package jaggregate.examples; import java.io.PrintStream; import jaggregate.BinaryFunctor; import jaggregate.Dictionary; import static jaggregate.Dictionary.*; import jaggregate.Pair; import static jaggregate.Pair.*; import static jaggregate.Set.*; import jaggregate.UnaryCondition; import jaggregate.UnaryFunctor; class DictionaryExample { public static void main( String[] args ) { Dictionary<String, Integer> lengths = emptyDictionary(); lengths.add( pair( "one", 3 ) ); lengths.addAll( pair( "two", 3 ), pair( "three", 5 ), pair( "four", 4 ) ); UnaryCondition<Pair<?, Integer>> valueLessThanFive = valueLessThan( 5 ); System.out.println( "all lengths < 5? " + lengths.allSatisfy( valueLessThanFive ) ); System.out.println( "any lengths < 5? " + lengths.anySatisfy( valueLessThanFive ) ); System.out.println( "length of 'two'? " + lengths.at( "two" ) ); System.out.println( "length of 'five'? " + lengths.at( "five" ) ); System.out.println( "concat key and value: " + lengths.collect( KEY_VALUE_CONCAT ) ); System.out.println( "squares of lengths: " + lengths.collectValues( SQUARE ) ); System.out.println( "here's a pair with length > 4: " + lengths.detect( valueGreaterThan( 4 ) ) ); lengths.forEachDo( printOnLinesTo( System.out ) ); System.out.println( "has 'four=4'? " + lengths.includes( pair( "four", 4 ) ) ); System.out.println( "has 'six=3'? " + lengths.includes( pair( "six", 3 ) ) ); System.out.println( "has 'two'? " + lengths.includesKey( "two" ) ); System.out.println( "has 'seven'? " + lengths.includesKey( "seven" ) ); System.out.println( "sum of values: " + lengths.inject( 0, SUM_OF_VALUES ) ); System.out.println( "better not be empty: " + lengths.isEmpty() ); System.out.println( "here's a key with value 3: " + lengths.keyAt( 3 ) ); System.out.println( "the keys: " + lengths.keys() ); lengths.keysAndValuesDo( CONCAT ); lengths.keysDo( printOnLinesTo( System.out ) ); setWith( "five", "six", "seven" ).forEachDo( mapLengthsInto( lengths ) ); System.out.println( "after additions: " + lengths ); } private static UnaryCondition<Pair<?, Integer>> valueLessThan( final int comparand ) { return new UnaryCondition<Pair<?, Integer>>() { public boolean matches( Pair<?, Integer> target ) { return target.value() < comparand; } }; } private static UnaryCondition<Pair<?, Integer>> valueGreaterThan( final int comparand ) { return new UnaryCondition<Pair<?, Integer>>() { public boolean matches( Pair<?, Integer> target ) { return target.value() > comparand; } }; } private static final UnaryFunctor<Pair<?, ?>, String> KEY_VALUE_CONCAT = new UnaryFunctor<Pair<?, ?>, String>() { public String evaluate( Pair<?, ?> target ) { return String.valueOf( target.key() )+ target.value(); } }; private static final UnaryFunctor<Integer, Integer> SQUARE = new UnaryFunctor<Integer, Integer>() { public Integer evaluate( Integer target ) { return target * target; } }; private static <A> UnaryFunctor<A, Void> printOnLinesTo( final PrintStream out ) { return new UnaryFunctor<A, Void>() { public Void evaluate( A target ) { out.println( target ); return null; } }; } private static final BinaryFunctor<Integer, Pair<?, Integer>, Integer> SUM_OF_VALUES = new BinaryFunctor<Integer, Pair<?, Integer>, Integer>() { public Integer evaluate( Integer first, Pair<?, Integer> second ) { return first + second.value(); } }; private static final BinaryFunctor<Object, Object, String> CONCAT = new BinaryFunctor<Object, Object, String>() { public String evaluate( Object first, Object second ) { return String.valueOf( first ) + second; } }; private static UnaryFunctor<String, Void> mapLengthsInto( final Dictionary<String, Integer> lengthMap ) { return new UnaryFunctor<String, Void>() { public Void evaluate( String target ) { lengthMap.putAt( target, target.length() ); return null; } }; } }
all lengths < 5? false any lengths < 5? true length of 'two'? 3 length of 'five'? null concat key and value: [three5,two3,four4,one3] squares of lengths: {[four=16],[two=9],[three=25],[one=9]} here's a pair with length > 4: three=5 four=4 two=3 three=5 one=3 has 'four=4'? true has 'six=3'? false has 'two'? true has 'seven'? false sum of values: 15 better not be empty: false here's a key with value 3: two the keys: [four,two,three,one] four two three one after additions: {[seven=5],[four=4],[two=3],[three=5],[five=4],[one=3],[six=3]}
Top

Iterables

Iterables extends the basic functionality of Jaggregate collections to Java Collections Framework classes or other classes which implement the new Java 5 interface Iterable.

package jaggregate.examples; import java.util.ArrayList; import static java.util.Arrays.*; import jaggregate.BinaryFunction; import jaggregate.BinaryFunctor; import static jaggregate.Comparables.*; import static jaggregate.Iterables.*; import jaggregate.UnaryCondition; import jaggregate.UnaryFunctor; class IterablesExample { public static void main( String[] args ) { Iterable<Integer> littleFibs = new ArrayList<Integer>( asList( 0, 1, 1, 2, 3, 5, 8 ) ); System.out.println( "all less than 10? " + allSatisfy( littleFibs, lessThan( 10 ) ) ); System.out.println( "any less than 0? " + anySatisfy( littleFibs, lessThan( 0 ) ) ); System.out.println( "squares: " ); for ( Integer each : collect( littleFibs, SQUARED ) ) System.out.println( each ); System.out.println( "first greater than 5: " + detect( littleFibs, greaterThan( 5 ) ) ); System.out.println( "sum: " + inject( littleFibs, 0, SUM ) ); System.out.println( "how many 1's? " + occurrencesOf( littleFibs, 1 ) ); System.out.println( "odds: " ); for ( Integer each : select( littleFibs, ODD ) ) System.out.println( each ); removeIf( littleFibs, ODD ); retainIf( littleFibs, lessThan( 5 ) ); System.out.println( "evens less than 5: " + littleFibs ); } private static final UnaryFunctor<Integer, Integer> SQUARED = new UnaryFunctor<Integer, Integer>() { public Integer evaluate( Integer target ) { return target * target; } }; private static final BinaryFunctor<Integer, Integer, Integer> SUM = new BinaryFunctor<Integer, Integer, Integer>() { public Integer evaluate( Integer first, Integer second ) { return first + second; } }; private static final UnaryCondition<Integer> ODD = new UnaryCondition<Integer>() { public boolean matches( Integer target ) { return (target & 1) != 0; } }; }
all less than 10? true any less than 0? false squares: 0 1 1 4 9 25 64 first greater than 5: 8 sum: 20 how many 1's? 2 odds: 1 1 3 5 evens less than 5: [0, 2]
Top