ch.lambdaj.Lambda Maven / Gradle / Ivy
// Modified or written by Ex Machina SAGL for inclusion with lambdaj.
// Copyright (c) 2009 Mario Fusco, Luca Marrocco.
// Licensed under the Apache License, Version 2.0 (the "License")
package ch.lambdaj;
import static ch.lambdaj.function.argument.ArgumentsFactory.*;
import static ch.lambdaj.function.closure.ClosuresFactory.*;
import static ch.lambdaj.function.matcher.HasArgumentWithValue.*;
import static ch.lambdaj.util.iterator.IteratorFactory.*;
import ch.lambdaj.util.iterator.*;
import java.util.*;
import org.hamcrest.*;
import ch.lambdaj.function.aggregate.*;
import ch.lambdaj.function.argument.*;
import ch.lambdaj.function.closure.*;
import ch.lambdaj.function.compare.*;
import ch.lambdaj.function.convert.*;
import ch.lambdaj.function.matcher.*;
import ch.lambdaj.proxy.*;
/**
* This class consists exclusively of static methods that allow to use all the core features of the lambdaj library.
* @author Mario Fusco
*/
@SuppressWarnings("unchecked")
public final class Lambda {
private Lambda() { }
/**
* Constructs a proxy object that mocks the given Class registering all the subsequent invocations on the object.
* @param clazz The class of the object to be mocked
* @return An object of the given class that register all the invocations made on it
*/
public static T on(Class clazz) {
return createArgument(clazz);
}
/**
* Returns the actual argument of the methods invocation sequence defined through the {@link Lambda#on(Class)} method.
* @param argumentPlaceholder The placeholder for this argument created using the {@link Lambda#on(Class)} method
* @return The actual argument of the methods invocation sequence defined through the {@link Lambda#on(Class)} method
*/
public static Argument argument(T argumentPlaceholder) {
return actualArgument(argumentPlaceholder);
}
/**
* Transforms a collection of Ts in a single object having the same methods of a single instance of T.
* That allows to invoke a method on each T in the collection with a single strong typed method call as in the following example:
*
* List<Person> personInFamily = asList(new Person("Domenico"), new Person("Mario"), new Person("Irma"));
* forEach(personInFamily).setLastName("Fusco");
*
* The actual class of T is inferred from the class of the first iterable's item, but you can
* specify a particular class by using the overloaded method.
* @param The type of the items in the iterable
* @param iterable The iterable to be transformed
* @return An object that proxies all the item in the iterable or null if the iterable is null or empty
* @throws IllegalArgumentException if the iterable is null or empty
*/
public static T forEach(Iterable extends T> iterable) {
ResettableIterator resettableIterator = (ResettableIterator)asResettableIterator(iterable);
if (!resettableIterator.hasNext())
throw new IllegalArgumentException("forEach() is unable to introspect on an empty iterator. Use the overloaded method accepting a class instead");
return ProxyIterator.createProxyIterator(resettableIterator, resettableIterator.next());
}
/**
* Transforms a collection of Ts in a single object having the same methods of a single instance of T.
* That allows to invoke a method on each T in the collection with a single strong typed method call.
* The actual class of T is inferred from the class of the first iterable's item, but you can
* specify a particular class by using the overloaded method.
* @param The type of the items in the iterable
* @param iterator The iterator to be transformed
* @return An object that proxies all the item in the iterator or null if the iterator is null or empty
* @throws IllegalArgumentException if the iterable is null or empty
*/
public static T forEach(Iterator extends T> iterator) {
if (!iterator.hasNext())
throw new IllegalArgumentException("forEach() is unable to introspect on an empty iterator. Use the overloaded method accepting a class instead");
ResettableIterator resettableIterator = (ResettableIterator)asResettableIterator(iterator);
return ProxyIterator.createProxyIterator(resettableIterator, resettableIterator.next());
}
/**
* Transforms a collection of Ts in a single object having the same methods of a single instance of T.
* That allows to invoke a method on each T in the collection with a single strong typed method call as in the following example:
*
* List<Person> personInFamily = asList(new Person("Domenico"), new Person("Mario"), new Person("Irma"));
* forEach(personInFamily, Person.class).setLastName("Fusco");
*
* The given class represents the proxied by the returned object, so it should be a superclass of all the objects in the iterable.
* This overloaded version should be always used when it is not insured that the given iterable is null or empty.
* @param The type of the items in the iterable
* @param iterable The iterable to be transformed
* @param clazz The class proxied by the returned object
* @return An object that proxies all the item in the iterable. If the given iterable is null or empty it returns
* an instance of T that actually proxies an empty Iterable of Ts
*/
public static T forEach(Iterable extends T> iterable, Class clazz) {
return ProxyIterator.createProxyIterator((ResettableIterator)asResettableIterator(iterable), clazz);
}
/**
* Transforms an iterator of Ts in a single object having the same methods of a single instance of T.
* That allows to invoke a method on each T in the iterator with a single strong typed method call.
* The actual class of T is inferred from the class of the first iterable's item, but you can
* specify a particular class by using the overloaded method.
* @param The type of the items in the iterator
* @param iterator The iterator to be transformed
* @param clazz The class proxied by the returned object
* @return An object that proxies all the item in the iterator or null if the iterator is null or empty
* @throws IllegalArgumentException if the iterator is null or empty
*/
public static T forEach(Iterator extends T> iterator, Class clazz) {
return ProxyIterator.createProxyIterator((ResettableIterator)asResettableIterator(iterator), clazz);
}
/**
* Transforms an array of Ts in a single object having the same methods of a single instance of T.
* That allows to invoke a method on each T in the array with a single strong typed method call.
* @param The type of the items in the array
* @param array The array to be transformed
* @return An object that proxies all the item in the array
*/
public static T forEach(T... array) {
return ProxyIterator.createProxyIterator((ResettableIterator)asResettableIterator(array), (Class)array[0].getClass());
}
// ////////////////////////////////////////////////////////////////////////
// /// Collection
// ////////////////////////////////////////////////////////////////////////
/**
* Flattens the given iterable by recursively descending through its nested Collections
* and create a flat List of all of the leaves.
* This method also works with Maps (by collecting their values) and arrays.
* @param iterable The iterable to be flattened
* @return The flattened iterable
*/
public static List flatten(Object iterable) {
return flattenIterator(iterable);
}
/**
* Collects the items in the given iterable putting them in a List.
* Actually it handles also Maps, Arrays and Iterator by collecting their values.
* Note that this method accepts an Object in order to be used in conjunction with the {@link Lambda#forEach(Iterable)}.
* @param iterable The iterable of which the items should be collected
* @return A List containing all the items collected from the give iterable
* @throws IllegalArgumentException if the iterable is not an Iterable or a Map
*/
public static List extends T> collect(Object iterable) {
List collected = new ArrayList();
Iterator i = asIterator(iterable);
while (i.hasNext()) {
Object item = i.next();
if (item instanceof Iterable) collected.addAll((Collection) collect(item));
else if (item instanceof Map) collected.addAll((Collection) collect(((Map,?>)item).values()));
else collected.add((T)item);
}
return collected;
}
/**
* For each item in the given iterable collects the value defined by the given argument and put them in a List.
* For example the following code:
*
* List<Person> myFriends = asList(new Person("Biagio", 39), new Person("Luca", 29), new Person("Celestino", 29));
* List<Integer> ages = collect(meAndMyFriends, on(Person.class).getAge());
*
* extracts the ages of all the Persons in the list and put them in a List of Integer.
*
* Actually it handles also Maps, Arrays and Iterator by collecting their values.
* Note that this method accepts an Object in order to be used in conjunction with the {@link Lambda#forEach(Iterable)}.
* @param iterable The iterable of which the items should be collected
* @param argument An argument defined using the {@link Lambda#on(Class)} method
* @return A List containing all the items collected from the give iterable
* @throws RuntimeException if the iterable is not an Iterable or a Map
*/
public static List collect(Object iterable, T argument) {
return (List)collect(convert(iterable, new ArgumentConverter © 2015 - 2025 Weber Informatics LLC | Privacy Policy