001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.util;
028:
029: import java.util.ArrayList;
030: import java.util.Collection;
031: import java.util.Collections;
032: import java.util.Comparator;
033: import java.util.List;
034:
035: /**
036: * Sortings is a set of utility methods which provide simple
037: * and/or fixed sorting functionality to JDK Collections Framework.
038: *
039: * The names of the methods are intended to echo CommonLisp functions
040: * with similar functionality.
041: *
042: * This is functionality which should be part of Java Collections framework
043: * but is sadly missing.
044: */
045:
046: public final class Sortings {
047:
048: /** Similar functionality to java.util.Collections.sort, except with
049: * several important extensions: the collection is sorted
050: * into a new Collection (actually an ArrayList), all Collections are
051: * sortable (not just Lists), and a key function may be specified, so
052: * that the elements are compared based on the results of the key rather
053: * than on the elements themselves.
054: * If Collection is a List, and the key is null, this is equivalent to
055: * something like Collections.sort(new ArrayList(collection), comparator);
056: *
057: * Currently, the key mapping may be evaluated multiple times for each element.
058: * A better implementation would evaluate the keys exactly once into an array
059: * and then sort the keys and objects at the same time.
060: */
061: public static Collection sort(Collection collection,
062: final Comparator comparator, final Mapping key) {
063: List l = new ArrayList(collection);
064: Comparator rcomp = comparator;
065: if (key != null) {
066: rcomp = new Comparator() {
067: public final int compare(Object o1, Object o2) {
068: return comparator.compare(key.map(o1), key.map(o2));
069: }
070: };
071: }
072: Collections.sort(l, rcomp);
073: return l;
074: }
075:
076: /** alias for sort(collection,comparator,null); **/
077: public static Collection sort(Collection collection,
078: Comparator comparator) {
079: return sort(collection, comparator, null);
080: }
081:
082: /** Like sort(collection, comparator, key) where comparator
083: * is defined as using the Comparable interface. Key may or may not
084: * be null. If key is non-null, the resulting objects of applying the
085: * key mapping must be Comparable.
086: **/
087: public static Collection sort(Collection collection,
088: final Mapping key) {
089: Comparator comp;
090: if (key == null) {
091: comp = new Comparator() {
092: public final int compare(Object o1, Object o2) {
093: return ((Comparable) o1).compareTo(o2);
094: }
095: };
096: } else {
097: comp = new Comparator() {
098: public final int compare(Object o1, Object o2) {
099: return ((Comparable) (key.map(o1))).compareTo(key
100: .map(o2));
101: }
102: };
103: }
104: return sort(collection, comp, null);
105: }
106:
107: /** Like Collections.sort except non-destructive **/
108: public static Collection sort(Collection collection) {
109: List l = new ArrayList(collection);
110: Collections.sort(l);
111: return l;
112: }
113:
114: //////
115: // destructive versions
116: //////
117:
118: /** destructive version of sort(Collection,Comparator,key). collection must
119: * implement the optional retainAll Collections framework method.
120: * @return the (modified) collection
121: **/
122: public static Collection sortInPlace(Collection collection,
123: Comparator comparator, Mapping key) {
124: Collection sorted = sort(collection, comparator, key);
125: collection.retainAll(sorted);
126: return collection;
127: }
128:
129: /** destructive version of sort(Collection, Comparator). collection must
130: * implement the optional retainAll Collections framework method.
131: * @return the (modified) collection
132: **/
133: public static Collection sortInPlace(Collection collection,
134: Comparator comparator) {
135: Collection sorted = sort(collection, comparator);
136: collection.retainAll(sorted);
137: return collection;
138: }
139:
140: /** destructive version of sort(Collection, Mapping). collection must
141: * implement the optional retainAll Collections framework method.
142: * @return the (modified) collection
143: **/
144: public static Collection sortInPlace(Collection collection,
145: final Mapping key) {
146: Collection sorted = sort(collection, key);
147: collection.retainAll(sorted);
148: return collection;
149: }
150:
151: /** destructive version of sort(Collection). collection must
152: * implement the optional retainAll Collections framework method.
153: * @return the (modified) collection
154: **/
155: public static Collection sortInPlace(Collection collection) {
156: Collection sorted = sort(collection);
157: collection.retainAll(sorted);
158: return collection;
159: }
160:
161: }
|