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
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]
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]
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
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]
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
Interval
s.
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
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]
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]
OrderedCollection
As the above examples suggest, an OrderedCollection
supports
the ExtensibleCollection
, Sequence
, and
ContractibleSequence
protocols. It most closely resembles a
java.util.ArrayList
.
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
. NaturallySortedCollection
s
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]
Dictionary
A Dictionary
is an ExtensibleCollection
of
Pair
s, 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]}
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]
© Copyright 2004-2008 Paul R. Holser, Jr. All rights reserved.
Last modified: $Id: examples.html,v 1.25 2008/07/10 16:22:08 pholser Exp $