001/*
002 * JPPF.
003 * Copyright (C) 2005-2018 JPPF Team.
004 * http://www.jppf.org
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.jppf.utils.collections;
019
020import java.lang.reflect.Array;
021import java.util.*;
022
023/**
024 * This class provides a set of utility methods for manipulating and converting
025 * collections and arrays.
026 * @author Laurent Cohen
027 */
028public final class CollectionUtils {
029  /**
030   * Instantiation of this class is not permitted.
031   */
032  private CollectionUtils() {
033  }
034
035  /**
036   * Convert an array into a <code>Set</code>.
037   * @param <T> the type of the elements in the array.
038   * @param array the array to convert.
039   * @return a set of elements with the same type as that of the array element type.
040   */
041  @SafeVarargs
042  public static <T> Set<T> set(final T... array) {
043    final Set<T> newSet = new HashSet<>(array.length);
044    for (final T element : array) newSet.add(element);
045    return newSet;
046  }
047
048  /**
049   * Convert an array into a <code>Set</code>.
050   * @param <T> the type of the elements in the array.
051   * @param clazz the class of the elements of the set to produce.
052   * @param array the array to convert.
053   * @return a set of elements with the same type as that of the array element type.
054   */
055  @SafeVarargs
056  public static <T> Set<T> setOf(@SuppressWarnings("unused") final Class<T> clazz, final T... array) {
057    final Set<T> newSet = new HashSet<>(array.length);
058    for (final T element : array) newSet.add(element);
059    return newSet;
060  }
061
062  /**
063   * Convert an array into a <code>List</code>.
064   * @param <T> the type of the elements in the array.
065   * @param array the array to convert.
066   * @return a list of elements with the same type as that of the array element type.
067   */
068  @SafeVarargs
069  public static <T> List<T> list(final T... array) {
070    final List<T> list = new ArrayList<>(array.length);
071    for (final T element : array) list.add(element);
072    return list;
073  }
074
075  /**
076   * Concatenate a set of array into a single array.
077   * @param <T> the element type of the arrays to concatenate.
078   * @param arrays the arrays to concatenate.
079   * @return an array whose size is the sum of the sizes of all the input arrays, and whose elements are all the elements found in all the input arrays.
080   */
081  @SuppressWarnings("unchecked")
082  public static <T> T[] concatArrays(final T[]... arrays) {
083    if (arrays == null) return null;
084    int size = 0;
085    for (T[] array : arrays) size += array.length;
086    final List<T> result = new ArrayList<>(size);
087    T[] tmp = null;
088    for (final T[] array : arrays) {
089      if (array.length > 0) {
090        tmp = array;
091        break;
092      }
093    }
094    if (tmp == null) return Arrays.copyOf(arrays[0], 0);
095    for (T[] array : arrays) {
096      for (T t : array) result.add(t);
097    }
098    return result.toArray((T[]) Array.newInstance(tmp[0].getClass(), 0));
099  }
100
101  /**
102   * Concatenate a set of array into a single array.
103   * @param <T> the element type of the arrays to concatenate.
104   * @param clazz the class of the elements of the array.
105   * @param arrays the arrays to concatenate.
106   * @return an array whose size is the sum of the sizes of all the input arrays, and whose elements are all the elements found in all the input arrays.
107   */
108  @SuppressWarnings("unchecked")
109  public static <T> T[] concatArrays(final Class<T> clazz, final T[]... arrays) {
110    if (arrays == null) return null;
111    int size = 0;
112    for (T[] array : arrays) size += array.length;
113    final List<T> result = new ArrayList<>(size);
114    T[] tmp = null;
115    for (final T[] array : arrays) {
116      if (array.length > 0) {
117        tmp = array;
118        break;
119      }
120    }
121    if (tmp == null) return Arrays.copyOf(arrays[0], 0);
122    for (T[] array : arrays) {
123      for (T t : array) result.add(t);
124    }
125    return result.toArray((T[]) Array.newInstance(clazz, 0));
126  }
127
128  /**
129   * Format a string with size information about a map whose values are lists of elements.
130   * @param <T> the type of the keys in the map.
131   * @param <U> the type of the values in the map.
132   * @param name an arbitrary name given to the map.
133   * @param map the map from which to get size information.
134   * @return a string containing information about the number of elements in the map.
135   */
136  public static <T, U> String formatSizeMapInfo(final String name, final CollectionMap<T, U> map) {
137    final StringBuilder sb = new StringBuilder();
138    sb.append(name).append("[shallow size=").append(map.size());
139    sb.append(", total elements=").append(map.size()).append(']');
140    return sb.toString();
141  }
142
143  /**
144   * Generate a list that contains the specified number of elements of the specified list,
145   * starting at the specified position in the specified list.
146   * @param <T> the type of the elements in the list.
147   * @param source the list from which to get the elements.
148   * @param start the start position in the source list.
149   * @param size the number of elements to get from the source list.
150   * @return the resulting list.
151   */
152  public static <T> List<T> getAllElements(final List<T> source, final int start, final int size) {
153    final List<T> result = new ArrayList<>(size);
154    for (int i = 0; i < size; i++) result.add(source.get(i + start));
155    return result;
156  }
157
158  /**
159   * Return the parameters as an array.
160   * @param <T> the ytpe of the elements in the array. Inferred as the common supertype of all the elements.
161   * @param elts the elements of the array.
162   * @return an array of the specified type.
163   */
164  @SafeVarargs
165  public static <T> T[] array(final T... elts) {
166    return elts;
167  }
168
169  /**
170   * Return the parameters as an array of Objects.
171   * @param elts the elements of the array.
172   * @return an array of <code>Object</code> instances.
173   */
174  public static Object[] objects(final Object... elts) {
175    return elts;
176  }
177
178  /**
179   * Print the content of a collection map in an easily readable way.
180   * @param map the map to print.
181   * @return a string with the map elements properly indented and formatted.
182   * @param <K> the type of the keys in the map.
183   * @param <V> the type of the values in the map.
184   */
185  public static <K, V> String prettyPrint(final CollectionMap<K, V> map) {
186    final StringBuilder sb = new StringBuilder();
187    sb.append("{\n");
188    int count1 = 0;
189    for (final K key : map.keySet()) {
190      if (count1 > 0) sb.append(",\n");
191      sb.append("  ").append(key).append(" = [\n");
192      int count2 = 0;
193      for (final V value : map.getValues(key)) {
194        if (count2 > 0) sb.append(",\n");
195        sb.append("    ").append(value);
196        count2++;
197      }
198      sb.append("\n  ]");
199      count1++;
200    }
201    sb.append("\n}");
202    return sb.toString();
203  }
204}