Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.sf.kdgcommons.collections.CollectionUtil Maven / Gradle / Ivy
Go to download
A collection of utility classes for Java, supplementing and in some cases
replacing Jakarta Commons and Google Guava.
// Copyright Keith D Gregory
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package net.sf.kdgcommons.collections;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.RandomAccess;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.regex.Pattern;
/**
* Static utility methods for working with collections -- particularly
* parameterized collections.
*/
public class CollectionUtil
{
/**
* Returns a set (HashSet
) containing the passed elements.
*/
public static HashSet asSet(T... elems)
{
HashSet result = new HashSet();
for (T elem : elems)
result.add(elem);
return result;
}
/**
* Returns a map (HashMap
) built from the passed elements. Elements
* alternate between keys and values, and if given an odd number of elements the
* last will be used as the key for a null value. Elements will be added in the
* order they appear as parameters, so repeating a key will mean that only the
* last value is stored.
*
* Note that the result is parameterized as Object,Object
; as there
* is no way to differentiate between keys and values with varargs, we have to
* use the lowest common denominator.
*
* @since 1.0.15
*/
public static HashMap asMap(Object... elems)
{
HashMap result = new HashMap();
for (int ii = 0 ; ii < elems.length ; ii += 2)
{
Object key = elems[ii];
Object value = (ii < elems.length - 1)
? elems[ii + 1]
: null;
result.put(key, value);
}
return result;
}
/**
* Appends an arbitrary number of explicit elements to an existing collection.
* Primarily useful when writing testcases.
*/
public static void addAll(Collection coll, T... elems)
{
for (T elem : elems)
coll.add(elem);
}
/**
* Appends the values returned by an iterator to the passed collection.
*/
public static void addAll(Collection coll, Iterator src)
{
while (src.hasNext())
coll.add(src.next());
}
/**
* Appends the contents of an iterable object to the passed collection.
*/
public static void addAll(Collection coll, Iterable src)
{
addAll(coll, src.iterator());
}
/**
* Adds a value to the collection if the boolean expression is true.
* Returns the collection as a convenience for chained invocations.
*
* @since 1.0.8
*/
public static Collection addIf(Collection coll, T value, boolean expr)
{
if (expr) coll.add(value);
return coll;
}
/**
* Adds a value to the collection if it's not null. Returns the collection
* as a convenience for chained invocations.
*
* @since 1.0.11
*/
public static Collection addIfNotNull(Collection coll, T value)
{
return addIf(coll, value, value != null);
}
/**
* Stores an entry in a map if the boolean expression is true. Returns the
* map as a convenience for chained invocations.
*
* @since 1.0.15
*/
public static Map putIf(Map map, K key, V value, boolean expr)
{
if (expr) map.put(key, value);
return map;
}
/**
* Stores an entry in a map if the value is not null
. Returns the
* map as a convenience for chained invocations.
*
* @since 1.0.15
*/
public static Map putIfNotNull(Map map, K key, V value)
{
return putIf(map, key, value, value != null);
}
/**
* Adds the specified item to a map if it does not already exist. Returns
* either the added item or the existing mapping.
*
* Note: The return behavior differs from Map.put()
,
* in that it returns the new value if there was no prior
* mapping. I find this more useful, as I typically want
* to do something with the mapping.
*
* Warning: This operation is not synchronized. In most cases, a
* better approach is to use {@link DefaultMap}, with a
* functor to generate new entries.
*
* @since 1.0.12
*/
public static V putIfAbsent(Map map, K key, V value)
{
if (! map.containsKey(key))
{
map.put(key,value);
return value;
}
return map.get(key);
}
/**
* Adds entries from add
to base
where there is not
* already a mapping with the same key.
*
* @since 1.0.14
*/
public static void putIfAbsent(Map base, Map add)
{
for (Map.Entry entry : add.entrySet())
putIfAbsent(base, entry.getKey(), entry.getValue());
}
/**
* Returns the first element of the passed list, null
if
* the list is empty or null.
*/
public static T first(List list) {
return isNotEmpty(list) ? list.get(0) : null;
}
/**
* Returns the last element of the passed list, null
if
* the list is empty or null. Uses an indexed get unless the list is
* a subclass of java.util.LinkedList
*/
public static T last(List list) {
if (isEmpty(list)) return null;
if (list instanceof LinkedList>) return ((LinkedList)list).getLast();
return list.get(list.size() - 1);
}
/**
* Verifies that the passed list contains only elements of the given type,
* and returns it as a parameterized list (does not create a new list).
*
* This function exists to avoid suppressing warnings in application code.
*
* @throws ClassCastException if any element is a different type.
*/
@SuppressWarnings("unchecked")
public static List cast(List> list, Class klass)
{
for (Object obj : list)
{
klass.cast(obj);
}
return (List)list;
}
/**
* Verifies that the passed set contains only elements of the given type,
* and returns it as a parameterized set (does not create a new set).
*
* This function exists to avoid suppressing warnings in application code.
*
* @throws ClassCastException if any element is a different type.
*/
@SuppressWarnings("unchecked")
public static Set cast(Set> set, Class klass)
{
for (Object obj : set)
{
klass.cast(obj);
}
return (Set)set;
}
/**
* Verifies that the passed map contains only keys and values of the given
* types, and returns it as a parameterized map (does not create a new map).
*
* This function exists to avoid suppressing warnings in application code.
*
* @throws ClassCastException if any key/value is a different type.
*
* @since 1.0.15
*/
@SuppressWarnings("unchecked")
public static Map cast(Map,?> map, Class keyClass, Class valueClass)
{
for (Map.Entry,?> entry : map.entrySet())
{
keyClass.cast(entry.getKey());
valueClass.cast(entry.getValue());
}
return (Map)map;
}
/**
* Resizes the passed list to N entries. Will add the specified object if
* the list is smaller than the desired size, discard trailing entries if
* larger. This is primarily used to presize a list that will be accessed
* by index, but it may also be used to truncate a list for display.
*
* @return The list, as a convenience for callers
*
* @throws UnsupportedOperationException if the list does not implement
* RandomAccess
and its list iterator does not
* support the remove()
operation
*/
public static List resize(List list, int newSize, T obj)
{
if (list instanceof ArrayList)
((ArrayList)list).ensureCapacity(newSize);
if (list.size() < newSize)
{
for (int ii = list.size() ; ii < newSize ; ii++)
list.add(obj);
}
else if (list.size() > newSize)
{
if (list instanceof RandomAccess)
{
for (int ii = list.size() - 1 ; ii >= newSize ; ii--)
list.remove(ii);
}
else
{
ListIterator itx = list.listIterator(newSize);
while (itx.hasNext())
{
itx.next();
itx.remove();
}
}
}
return list;
}
/**
* Resizes the passed list to N entries. Will add nulls if the list is
* smaller than the desired size, discard trailing entries if larger.
* This is primarily used to presize a list that will be accessed by
* index, but it may also be used to truncate a list for display.
*
* @return The list, as a convenience for callers
* @throws UnsupportedOperationException if the list does not implement
* RandomAccess
and its list iterator does not
* support the remove()
operation
*/
public static List resize(List list, int newSize)
{
return resize(list, newSize, null);
}
/**
* Iterates the passed collection, converts its elements to strings, then
* concatenates those strings with the specified delimiter between them.
* Nulls are converted to empty strings.
*
* @since 1.0.2
*/
public static String join(Iterable coll, String delim)
{
if (coll == null)
return "";
boolean isFirst = true;
StringBuilder buf = new StringBuilder(1024);
for (T item : coll)
{
if (isFirst)
isFirst = false;
else
buf.append(delim);
if (item != null)
buf.append(String.valueOf(item));
}
return buf.toString();
}
/**
* Adds all elements of the src
collections to dest
,
* returning dest
. This is typically used when you need to combine
* collections temporarily for a method argument.
*
* Warning: this mutates the provided list. In version 2.0
* it will create a new list, with a variant of addAll()
that mutates
* the list.
*
* @since 1.0.7
*/
public static List combine(List dest, Collection... src)
{
for (Collection cc : src)
{
dest.addAll(cc);
}
return dest;
}
/**
* Adds all elements of the src
collections to dest
,
* returning dest
. This is typically used when you need to combine
* collections temporarily for a method argument.
*
* Warning: this mutates the provided set. In version 2.0
* it will create a new set, with a variant of addAll()
that mutates
* the set.
*
* @since 1.0.7
*/
public static Set combine(Set dest, Collection... src)
{
for (Collection cc : src)
{
dest.addAll(cc);
}
return dest;
}
/**
* Adds all elements of the src
collections to dest
,
* returning dest
. This is typically used when you need to combine
* collections temporarily for a method argument.
*
* Note: source maps are added in order; if the same keys are present in multiple
* sources, the last one wins.
*
*
Warning: this mutates the provided map. In version 2.0
* it will create a new map, with a variant of putAll()
that mutates
* the map.
*
* @since 1.0.7
*/
public static Map combine(Map dest, Map... src)
{
for (Map cc : src)
{
dest.putAll(cc);
}
return dest;
}
/**
* Returns true
if the passed collection is either null
* or has size 0.
*/
public static boolean isEmpty(Collection> c)
{
return (c == null)
? true
: (c.size() == 0);
}
/**
* Returns true
if the passed collection is not null
* and has size > 0.
*/
public static boolean isNotEmpty(Collection> c)
{
return (c != null) && (c.size() > 0);
}
/**
* Returns true
if the passed map is either null
* or has size 0.
*/
public static boolean isEmpty(Map,?> m)
{
return (m == null)
? true
: (m.size() == 0);
}
/**
* Returns true
if the passed map is not null
* and has size > 0.
*/
public static boolean isNotEmpty(Map,?> m)
{
return (m != null) && (m.size() > 0);
}
/**
* Compares two collections of Comparable
elements. The two collections are
* iterated, and the first not-equal compareTo()
result is returned. If the
* collections are of equal length and contain the same elements in iteration order, they
* are considered equal. If they are of unequal length but contain the same elements in
* iteration order, the shorter is considered less than the longer.
*
* Note that two collections that are equal based on their intrinsic equals()
* method, but iterate in a different order (ie, hash-based collections) are not considered
* equal by this method.
*
* @since 1.0.14
*/
@SuppressWarnings("rawtypes")
public static int compare(Collection extends Comparable> c1, Collection extends Comparable> c2)
{
Iterator extends Comparable> itx1 = c1.iterator();
Iterator extends Comparable> itx2 = c2.iterator();
while (itx1.hasNext())
{
if (! itx2.hasNext())
return 1;
Comparable v1 = itx1.next();
Comparable v2 = itx2.next();
int cmp = v1.compareTo(v2);
if (cmp != 0)
return cmp;
}
if (itx2.hasNext())
return -1;
else
return 0;
}
/**
* Returns the second iterable if the first is null. This is used for a null-safe
* for loop.
*/
public static Iterable defaultIfNull(Iterable reg, Iterable def)
{
return (reg == null) ? def : reg;
}
/**
* Returns the default collection if the regular object is null or empty.
*/
public static Collection defaultIfEmpty(Collection reg, Collection def)
{
return ((reg == null) || (reg.size() == 0)) ? def : reg;
}
/**
* Retrieves a value from a nested collection hierarchy by following a sequence
* of keys. Supports arbitrary nesting of maps, arrays, and lists.
*
* Example; given:
*
* Map<String,Object> bottom = new HashMap<>();
* bottom.put("argle", "bargle");
*
* List<Object> middle = new ArrayList<>();
* middle.add(bottom);
*
* Map<String,Object> top = new HashMap<>();
* top.put("foo", middle);
*
* Then:
*
*
* CollectionUtil.getVia(top, "foo", 0, "argle");
returns "bargle"
.
* CollectionUtil.getVia(top, "bar", 0, "argle");
returns null
.
* CollectionUtil.getVia(top, "foo", "junk", "argle");
throws IllegalArgumentException
.
*
*
* @param root The root object.
* @param keys One or more keys. The first key is applied to the root object,
* the second key is applied to the result of that, and so on.
* Arrays and lists may only be accessed via numeric keys; maps
* may be accessed via any type of key.
*
* @return The object located via the sequence of keys, null
if
* any key along the path does not resolve to an object.
*
* @throws IllegalArgumentException if any object found during the traversal is
* not a valid collection type, or if the key is not appropriate for the
* collection.
*
* @since 1.0.15
*/
public static Object getVia(Object root, Object... keys)
{
Object current = root;
// I iterate by index rather than for-in so that I can construct exceptions
for (int ii = 0 ; ii < keys.length ; ii++)
{
try
{
Object key = keys[ii];
if (current == null)
{
return null;
}
if (current instanceof Map)
{
current = ((Map)current).get(key);
}
else if (current instanceof List)
{
int index = ((Number)key).intValue();
List list = (List)current;
current = (index < list.size())
? list.get(index)
: null;
}
else if (current.getClass().isArray())
{
int index = ((Number)key).intValue();
current = (index < Array.getLength(current))
? Array.get(current, index)
: null;
}
else
{
List currentKeys = Arrays.asList(keys).subList(0, ii+1);
throw new IllegalArgumentException(
"attempted to get from " + current.getClass().getName()
+ " (path: " + currentKeys + ")");
}
}
catch (ClassCastException ex)
{
// I believe this is the only way that we can get here ...
List currentKeys = Arrays.asList(keys).subList(0, ii+1);
throw new IllegalArgumentException(
"attempted to get from " + current.getClass().getName() + " with non-numeric index"
+ " (path: " + currentKeys + ")");
}
}
return current;
}
/**
* Applies the specified functor to every element of the given collection, in
* its natural iteration order, and returns a list of the results.
*
* If the functor throws, it will be rethrown in a {@link CollectionUtil.MapException},
* which provides detailed information and partial work.
*
* @since 1.0.10
*
* @deprecated
* This function has been made obsolete by Java8. It will be removed in version 2.0.
*/
@Deprecated
public static List map(Collection coll, IndexValueMapFunctor functor)
{
List result = new ArrayList(coll.size());
int index = 0;
for (V value : coll)
{
try
{
result.add(functor.invoke(index, value));
index++;
}
catch (Throwable ex)
{
throw new MapException(ex, index, value, result);
}
}
return result;
}
/**
* Performs a parallel map operation. For each element in the source collection,
* a callable is dispatched to the passed ExecutorService
to invoke
* the specified functor. The results are accumulated and returned as a list, in
* the order of the original collection's iterator.
*
* If any element causes an exception, this method throws {@link CollectionUtil.MapException}.
* While that exception returns partial results, there is no guarantee that the
* results represent a particular range of the source collection.
*
* This method will wait until all of the elements of the collection have been
* processed, unless it is interrupted. If multiple invocations threw, one will
* be chosen arbitrarily; there is no guarantee that it represents the first
* collection element to cause an exception.
*
* @since 1.0.10
*
* @deprecated
* This function has been made obsolete by Java8. It will be removed in version 2.0.
*/
@Deprecated
public static List map(ExecutorService threadpool, Collection values, final IndexValueMapFunctor functor)
throws InterruptedException
{
int count = values.size();
ArrayList values2 = new ArrayList(values);
ArrayList> futures = new ArrayList>(count);
ArrayList results = new ArrayList();
resize(results, count);
for (int ii = 0 ; ii < count ; ii++)
{
final int index = ii;
final V value = values2.get(ii);
futures.add(threadpool.submit(new Callable()
{
public R call() throws Exception
{
return functor.invoke(index, value);
}
}));
}
int failureIndex = 0;
Throwable failureException = null;
for (int ii = 0 ; ii < count ; ii++)
{
Future future = futures.get(ii);
try
{
results.set(ii, future.get());
}
catch (CancellationException ex)
{
// I don't think we can ever get this exception, since we
// don't let the Future escape (and immediate shutdown of
// the pool should create an ExecutionException); but, we
// should treat it differently if we ever do get it
failureIndex = ii;
failureException = ex;
}
catch (ExecutionException ex)
{
failureIndex = ii;
failureException = ex.getCause();
}
}
if (failureException != null)
throw new MapException(failureException, failureIndex, values2.get(failureIndex), results);
else
return results;
}
/**
* Applies the specified functor to every element in the given collection, with
* the expectation that it will return a single value based on the item and any
* previous value.
*
* @since 1.0.10
*
* @deprecated
* This function has been made obsolete by Java8. It will be removed in version 2.0.
*/
@Deprecated
public static R reduce(Collection coll, IndexValueReduceFunctor functor)
{
R pendingResult = null;
int index = 0;
for (V value : coll)
{
try
{
pendingResult = functor.invoke(index, value, pendingResult);
index++;
}
catch (Throwable ex)
{
throw new ReduceException(ex, index, value, pendingResult);
}
}
return pendingResult;
}
/**
* Applies the specified predicate functor to every element of a collection,
* in its natural iteration order, and returns a list containing only those
* elements for which the predicate returned true
.
*
* If the functor throws, it will be rethrown in a {@link CollectionUtil.FilterException},
* which provides detailed information and partial work.
*
* @since 1.0.11
*
* @deprecated
* This function has been made obsolete by Java8. It will be removed in version 2.0.
*/
@Deprecated
public static List filter(Collection coll, Predicate predicate)
{
List result = new ArrayList(coll.size());
int index = 0;
for (V value : coll)
{
try
{
if (predicate.invoke(index, value))
{
result.add(value);
}
index++;
}
catch (Throwable ex)
{
throw new FilterException(ex, index, value, result);
}
}
return result;
}
/**
* Applies the given regex to the string value of every item in the passed
* list, building a new list from those value that either match or do not
* match. Null entries are treated as an empty string for matching, but
* will be returned as null.
*
* @since 1.0.3
*
* @param list The source list; this is unmodified.
* @param regex Regex applied to every string in the list.
* @param include If true
, strings that match are copied
* to the output list; if false
, strings
* that don't match are copied.
*
* @deprecated
* This function has been made obsolete by Java8. It will be removed in version 2.0.
*/
@Deprecated
public static List filter(List list, String regex, final boolean include)
{
final Pattern pattern = Pattern.compile(regex);
return filter(list, new Predicate()
{
public boolean invoke(int index, T value) throws Exception
{
String str = (value == null) ? "" : value.toString();
return pattern.matcher(str).matches() == include;
}
});
}
/**
* Partitions the passed iterable into N sublists, each of which has
* at most maxSize
elements.
*/
public static List> partition(Iterable source, int maxSize)
{
if (source == null) return Collections.emptyList();
List> result = new ArrayList>();
List sublist = new ArrayList(maxSize);
int count = 0;
for (T item : source)
{
sublist.add(item);
count++;
if (count >= maxSize)
{
result.add(sublist);
sublist = new ArrayList(maxSize);
count = 0;
}
}
if (sublist.size() > 0)
{
result.add(sublist);
}
return result;
}
/**
* Returns a map that contains all keys in the specified collection.
*
* The returned map is a HashMap; see variant for choosing map type.
*/
public static Map submap(Map src, Collection keys)
{
return submap(src, keys, new HashMap());
}
/**
* Extracts all mappings from the source map that correspond to the passed
* keys, and stores them in the destination map. Returns the destination
* map as a convenience.
*/
public static Map submap(Map src, Collection keys, Map dest)
{
if ((src == null) || (keys == null) || (dest == null))
{
return dest;
}
for (K key : keys)
{
if (src.containsKey(key))
{
dest.put(key, src.get(key));
}
}
return dest;
}
//----------------------------------------------------------------------------
// Supporting Objects
//----------------------------------------------------------------------------
/**
* A functor interface for {@link #map}. The {@link #invoke} function is
* called for every element in the collection, and is passed the element
* value and its position (0-based) in the iteration order.
*
* The implementation is permitted to throw anything, checked or not.
*
* @since 1.0.10
*
* @deprecated
* This interface has been made obsolete by Java8. It will be removed in version 2.0.
*/
@Deprecated
public interface IndexValueMapFunctor
{
public R invoke(int index, V value)
throws Exception;
}
/**
* An exception wrapper for {@link #map}. Contains the wrapped exception,
* the value and index that caused the exception, and the results-to-date.
*
* Note: because Java does not allow parameterization of Throwable
* subclasses (JLS 8.1.2), the value and results are held as Object
s.
*
* @since 1.0.10
*
* @deprecated
* This class has been made obsolete by Java8. It will be removed in version 2.0.
*/
@Deprecated
public static class MapException
extends RuntimeException
{
private static final long serialVersionUID = 1;
private int _index;
private Object _value;
private List> _partialResults;
public MapException(Throwable cause, int index, Object value, List> partialResults)
{
super(cause);
_index = index;
_value = value;
_partialResults = partialResults;
}
/**
* Returns the position (0-based) in the original collection's iteration where the
* wrapped exception was thrown.
*/
public int getIndex()
{
return _index;
}
/**
* Returns the value that caused the exception.
*/
public Object getValue()
{
return _value;
}
/**
* Returns any partial results from the map operation.
*
* Warning: the contents of this list are undefined in the case of a parallel map
* operation.
*/
public List> getPartialResults()
{
return _partialResults;
}
}
/**
* A functor used for the {@link #reduce} operation. The {@link #invoke}
* function is called for every element of a collection, and is responsible
* for aggregating the results. On the first invocation, the "pending"
* result is null
; on subsequent invocations, it is the value
* returned from the previous invocation.
*
* @since 1.0.10
*
* @deprecated
* This interface has been made obsolete by Java8. It will be removed in version 2.0.
*/
@Deprecated
public interface IndexValueReduceFunctor
{
public R invoke(int index, V value, R pendingResult)
throws Exception;
}
/**
* An exception wrapper for {@link #reduce}. Contains the wrapped exception,
* the value and index that caused the exception, and the results-to-date.
*
* Note: because Java does not allow parameterization of Throwable
* subclasses (JLS 8.1.2), the value and results are held as Object
s.
*
* @since 1.0.10
*
* @deprecated
* This class has been made obsolete by Java8. It will be removed in version 2.0.
*/
@Deprecated
public static class ReduceException
extends RuntimeException
{
private static final long serialVersionUID = 1;
private int _index;
private Object _value;
private Object _partialResults;
public ReduceException(Throwable cause, int index, Object value, Object partialResults)
{
super(cause);
_index = index;
_value = value;
_partialResults = partialResults;
}
/**
* Returns the position (0-based) in the original collection's iteration where the
* wrapped exception was thrown.
*/
public int getIndex()
{
return _index;
}
/**
* Returns the value that caused the exception.
*/
public Object getValue()
{
return _value;
}
/**
* Returns any partial results. This is the pendingResult
* value passed to the functor at the time the exception was thrown.
*/
public Object getPartialResults()
{
return _partialResults;
}
}
/**
* Implement this for the {@link #filter} operation: return true
to
* include an element in the result, false
to skip it. Implementations
* may throw exceptions; these will cause the filter to stop processing.
*
* Purists may object, but each invocation is given the element index, in iteration
* order.
*
* @since 1.0.11
*
* @deprecated
* This interface has been made obsolete by Java8. It will be removed in version 2.0.
*/
@Deprecated
public interface Predicate
{
public boolean invoke(int index, V value)
throws Exception;
}
/**
* An exception wrapper for {@link #filter}. Contains the wrapped exception,
* the value and index that caused the exception, and the results-to-date.
*
* Note: because Java does not allow parameterization of Throwable
* subclasses (JLS 8.1.2), the value and results are held as Object
s.
*
* @deprecated
* This class has been made obsolete by Java8. It will be removed in version 2.0.
*
* @since 1.0.11
*/
@Deprecated
public static class FilterException
extends RuntimeException
{
private static final long serialVersionUID = 1;
private int _index;
private Object _value;
private List> _partialResults;
public FilterException(Throwable cause, int index, Object value, List> partialResults)
{
super(cause);
_index = index;
_value = value;
_partialResults = partialResults;
}
/**
* Returns the position (0-based) in the original collection's iteration where the
* wrapped exception was thrown.
*/
public int getIndex()
{
return _index;
}
/**
* Returns the value that caused the exception.
*/
public Object getValue()
{
return _value;
}
/**
* Returns any partial results from the map operation.
*
* Warning: the contents of this list are undefined in the case of a parallel map
* operation.
*/
public List> getPartialResults()
{
return _partialResults;
}
}
}