Jaggregate version 3.2.1
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 jaggregate.BinaryFunction;
import jaggregate.Collection;
import jaggregate.UnaryFunction;
import jaggregate.UnaryPredicate;
import static jaggregate.Bag.bagWith;
import static jaggregate.Strings.LENGTH;
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 UnaryPredicate<String> EVEN_LENGTH =
new UnaryPredicate<String>() {
@Override
public boolean matches( String target ) {
return target != null && EVEN.matches( target.length() );
}
};
private static final UnaryPredicate<Integer> EVEN =
new UnaryPredicate<Integer>() {
@Override
public boolean matches( Integer target ) {
return target != null && ( target & 1 ) == 0;
}
};
private static <A> UnaryFunction<A, Object> printOnLinesTo(
final PrintStream out ) {
return new UnaryFunction<A, Object>() {
@Override
public Object evaluate( A target ) {
out.println( target );
return this;
}
};
}
private static BinaryFunction<Integer, Integer, Integer> SUM =
new BinaryFunction<Integer, Integer, Integer>() {
@Override
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 jaggregate.ExtensibleCollection;
import static jaggregate.Bag.bagWith;
import static jaggregate.Comparables.greaterThan;
import static jaggregate.Objects.equalTo;
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.setWith;
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@7,java.lang.Integer@5,java.lang.Integer@7,java.lang.Integer@3,java.lang.Integer@2]
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 jaggregate.IdentitySet;
import static jaggregate.Bag.bagWith;
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@7,java.lang.Integer@7,java.lang.Integer@2,java.lang.Integer@3,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.BinaryFunction;
import jaggregate.ReadOnlySequence;
import jaggregate.UnaryFunction;
import jaggregate.UnaryPredicate;
import static jaggregate.OrderedCollection.orderedCollectionWith;
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 BinaryFunction<Integer, String, Object>() {
@Override
public Object evaluate( Integer first, String second ) {
System.out.println( first + " = " + second );
return this;
}
} );
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> UnaryFunction<E, Object> printOnLinesTo(
final PrintStream sink ) {
return new UnaryFunction<E, Object>() {
@Override
public Object evaluate( E target ) {
sink.println( target );
return this;
}
};
}
private static <E> BinaryFunction<Integer, E, Object> printWithIndexOn(
final PrintStream sink ) {
return new BinaryFunction<Integer, E, Object>() {
@Override
public Object evaluate( Integer index, E element ) {
sink.println( "element at index " + index + ": " + element );
return this;
}
};
}
private static UnaryPredicate<Integer> divisibleBy( final int divisor ) {
return new UnaryPredicate<Integer>() {
@Override
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
Intervals.
package jaggregate.examples;
import java.io.PrintStream;
import jaggregate.ReadOnlySequence;
import jaggregate.UnaryFunction;
import static jaggregate.Interval.fromTo;
import static jaggregate.Interval.fromToBy;
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> UnaryFunction<A, Object> printOnLinesTo(
final PrintStream out ) {
return new UnaryFunction<A, Object>() {
@Override
public Object evaluate( A target ) {
out.println( target );
return this;
}
};
}
}
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 jaggregate.Sequence;
import static jaggregate.Arrays.arrayWith;
import static jaggregate.OrderedCollection.orderedCollectionWith;
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.orderedCollectionWith;
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. NaturallySortedCollections
accept elements which are already Comparable, so that the
elements' natural ordering is used.
package jaggregate.examples;
import java.util.Comparator;
import java.io.Serializable;
import jaggregate.NaturallySortedCollection;
import jaggregate.SortedCollection;
import static jaggregate.NaturallySortedCollection.naturallySortedCollectionFrom;
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
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.BinaryFunction;
import jaggregate.Dictionary;
import jaggregate.Pair;
import jaggregate.UnaryFunction;
import jaggregate.UnaryPredicate;
import static jaggregate.Dictionary.emptyDictionary;
import static jaggregate.Pair.pair;
import static jaggregate.Set.setWith;
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 ) );
UnaryPredicate<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 UnaryPredicate<Pair<?, Integer>> valueLessThan(
final int comparand ) {
return new UnaryPredicate<Pair<?, Integer>>() {
@Override
public boolean matches( Pair<?, Integer> target ) {
return target.value() < comparand;
}
};
}
private static UnaryPredicate<Pair<?, Integer>> valueGreaterThan(
final int comparand ) {
return new UnaryPredicate<Pair<?, Integer>>() {
@Override
public boolean matches( Pair<?, Integer> target ) {
return target.value() > comparand;
}
};
}
private static final UnaryFunction<Pair<?, ?>, String> KEY_VALUE_CONCAT =
new UnaryFunction<Pair<?, ?>, String>() {
@Override
public String evaluate( Pair<?, ?> target ) {
return String.valueOf( target.key() )+ target.value();
}
};
private static final UnaryFunction<Integer, Integer> SQUARE =
new UnaryFunction<Integer, Integer>() {
@Override
public Integer evaluate( Integer target ) {
return target * target;
}
};
private static <A> UnaryFunction<A, Object> printOnLinesTo(
final PrintStream out ) {
return new UnaryFunction<A, Object>() {
@Override
public Object evaluate( A target ) {
out.println( target );
return this;
}
};
}
private static final
BinaryFunction<Integer, Pair<?, Integer>, Integer> SUM_OF_VALUES =
new BinaryFunction<Integer, Pair<?, Integer>, Integer>() {
@Override
public Integer evaluate( Integer first, Pair<?, Integer> second ) {
return first + second.value();
}
};
private static final BinaryFunction<Object, Object, String> CONCAT =
new BinaryFunction<Object, Object, String>() {
@Override
public String evaluate( Object first, Object second ) {
return String.valueOf( first ) + second;
}
};
private static UnaryFunction<String, Object> mapLengthsInto(
final Dictionary<String, Integer> lengthMap ) {
return new UnaryFunction<String, Object>() {
@Override
public Object evaluate( String target ) {
lengthMap.putAt( target, target.length() );
return this;
}
};
}
}
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.asList;
import jaggregate.BinaryFunction;
import jaggregate.UnaryFunction;
import jaggregate.UnaryPredicate;
import static jaggregate.Comparables.greaterThan;
import static jaggregate.Comparables.lessThan;
import static jaggregate.Iterables.*;
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 UnaryFunction<Integer, Integer> SQUARED =
new UnaryFunction<Integer, Integer>() {
@Override
public Integer evaluate( Integer target ) {
return target * target;
}
};
private static final BinaryFunction<Integer, Integer, Integer> SUM =
new BinaryFunction<Integer, Integer, Integer>() {
@Override
public Integer evaluate( Integer first, Integer second ) {
return first + second;
}
};
private static final UnaryPredicate<Integer> ODD =
new UnaryPredicate<Integer>() {
@Override
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.24 2008/03/26 18:01:19 pholser Exp $