001    /**
002     * Copyright (c) 2012, SIB. All rights reserved.
003     * 
004     * SIB (Swiss Institute of Bioinformatics) - http://www.isb-sib.ch Host -
005     * http://javaprotlib.sourceforge.net/
006     * 
007     * Redistribution and use in source and binary forms, with or without
008     * modification, are permitted provided that the following conditions are met:
009     * Redistributions of source code must retain the above copyright notice, this
010     * list of conditions and the following disclaimer. Redistributions in binary
011     * form must reproduce the above copyright notice, this list of conditions and
012     * the following disclaimer in the documentation and/or other materials provided
013     * with the distribution. Neither the name of the SIB/GENEBIO nor the names of
014     * its contributors may be used to endorse or promote products derived from this
015     * software without specific prior written permission.
016     * 
017     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
018     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
019     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
020     * ARE DISCLAIMED. IN NO EVENT SHALL SIB/GENEBIO BE LIABLE FOR ANY DIRECT,
021     * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022     * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023     * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
024     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026     * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027     */
028    package org.expasy.jpl.commons.collection;
029    
030    
031    import java.util.ArrayList;
032    import java.util.Arrays;
033    import java.util.HashSet;
034    import java.util.List;
035    import java.util.Set;
036    import java.util.TreeSet;
037    import org.apache.commons.collections15.Transformer;
038    import org.expasy.jpl.commons.base.string.StringConverters;
039    
040    
041    /**
042     * Provides static utility method for {@code Collection}s.
043     * 
044     * @author nikitin
045     * 
046     * @version 1.0
047     * 
048     */
049    public class CollectionUtils {
050            
051            /**
052             * Create a new instance of {@code HashSet} from a list of elements.
053             * 
054             * @param <T> the data type.
055             * @param elts the elements to fill the set.
056             * @return a new instance of HashSet<T>.
057             */
058            public static final <T> HashSet<T> asSet(T... elts) {
059                    return new HashSet<T>(Arrays.asList(elts));
060            }
061            
062            /**
063             * Create a new instance of {@code TreeSet} from a list of elements.
064             * 
065             * @param <T> the data type.
066             * @param elts the elements to fill the set.
067             * @return a new instance of TreeSet<T>.
068             */
069            public static final <T> TreeSet<T> asTreeSet(T... elts) {
070                    return new TreeSet<T>(Arrays.asList(elts));
071            }
072            
073            /**
074             * Compute the intersection between the 2 given sets.
075             * 
076             * @param <T> the data type.
077             * @param s1 the first set.
078             * @param s2 the second set.
079             * @return an intersection of sets.
080             */
081            public static final <T> Set<T> intersection(Set<T> s1, Set<T> s2) {
082                    Set<T> inter = new HashSet<T>();
083                    
084                    Set<T> biggerSet = null;
085                    Set<T> smallerSet = null;
086                    
087                    if (s1.size() > s2.size()) {
088                            biggerSet = s1;
089                            smallerSet = s2;
090                    } else {
091                            smallerSet = s1;
092                            biggerSet = s2;
093                    }
094                    
095                    // quicker if test elements from the smaller set
096                    for (T elt : smallerSet) {
097                            if (biggerSet.contains(elt)) {
098                                    inter.add(elt);
099                            }
100                    }
101                    
102                    return inter;
103            }
104            
105            /**
106             * Compute the union of many sets.
107             * 
108             * @param <T> the data type.
109             * @param sets the sets to merge.
110             * @return a union of sets.
111             */
112            public static final <T> Set<T> union(Set<T>... sets) {
113                    Set<T> union = new HashSet<T>();
114                    
115                    for (Set<T> set : sets) {
116                            union.addAll(set);
117                    }
118                    
119                    return union;
120            }
121            
122            /**
123             * Compute s1 - s2.
124             * 
125             * @param <T> the data type.
126             * @param s1 the first set.
127             * @param s2 the second set.
128             * @return a substraction of sets.
129             */
130            public static final <T> Set<T> minus(Set<T> s1, Set<T> s2) {
131                    Set<T> diff = new HashSet<T>();
132                    
133                    diff.addAll(s1);
134                    diff.removeAll(s2);
135                    
136                    return diff;
137            }
138            
139            /**
140             * Keep all integers that belong to the interval.
141             * 
142             * @param s the set to set element from.
143             * @param from the lower bound of the interval.
144             * @param to the upper bound.
145             * @return a set of integers.
146             */
147            public static final Set<Integer> select(Set<Integer> s, int from, int to) {
148                    return select(s, new Interval.Builder(from, to).build());
149            }
150            
151            /**
152             * Keep all integers that belong to the interval.
153             * 
154             * @param s the set to set element from.
155             * @param interval the interval.
156             * @return a set of integers.
157             */
158            public static final Set<Integer> select(Set<Integer> s, Interval interval) {
159                    
160                    Set<Integer> set = new HashSet<Integer>(s);
161                    
162                    for (int elt : s) {
163                            if (!interval.contains(elt)) {
164                                    set.remove(elt);
165                            }
166                    }
167                    
168                    return set;
169            }
170            
171            /**
172             * Convert a string to a List<E>.
173             * 
174             * @param <E> the element type.
175             * @param str the string to parse list from (format="[?elt1,..,eltn]?").
176             * @param transformer the converter String to E.
177             * @return a list of E.
178             * 
179             * @see StringConverters
180             */
181            public static final <E> List<E> parseList(String str,
182                Transformer<String, E> transformer) {
183                    List<E> list = new ArrayList<E>();
184                    
185                    str = str.replace("[", "").replace("]", "");
186                    
187                    String[] elts = str.split(",\\s*");
188                    for (String elt : elts) {
189                            E field = transformer.transform(elt);
190                            list.add(field);
191                    }
192                    
193                    return list;
194            }
195            
196            public static final List<Integer> parseIntList(String str) {
197                    return parseList(str, StringConverters.STR_2_INT);
198            }
199            
200            public static final List<Double> parseDoubleList(String str) {
201                    return parseList(str, StringConverters.STR_2_DBL);
202            }
203            
204            public static final List<String> parseStringList(String str) {
205                    return parseList(str, StringConverters.STR_2_STR);
206            }
207    }