001/*
002 * JPPF.
003 * Copyright (C) 2005-2016 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  public static <T> Set<T> set(final T... array) {
042    Set<T> newSet = new HashSet<>(array.length);
043    for (T element : array) newSet.add(element);
044    return newSet;
045  }
046
047  /**
048   * Convert an array into a <code>List</code>.
049   * @param <T> the type of the elements in the array.
050   * @param array the array to convert.
051   * @return a list of elements with the same type as that of the array element type.
052   */
053  public static <T> List<T> list(final T... array) {
054    List<T> list = new ArrayList<>(array.length);
055    for (T element : array) list.add(element);
056    return list;
057  }
058
059  /**
060   * Concatenate a set of array into a single array.
061   * @param <T> the element type of the arrays to concatenate.
062   * @param arrays the arrays to concatenate.
063   * @return an array whose size is the sum of the sizes of all the input arrays, and whose elements are all the
064   *         elements found in all the input arrays.
065   */
066  @SuppressWarnings("unchecked")
067  public static <T> T[] concatArrays(final T[]... arrays) {
068    if (arrays == null) return null;
069    int size = 0;
070    for (T[] array : arrays)
071      size += array.length;
072    List<T> result = new ArrayList<>(size);
073    T[] tmp = null;
074    for (T[] array : arrays) {
075      if (array.length > 0) {
076        tmp = array;
077        break;
078      }
079    }
080    if (tmp == null) return Arrays.copyOf(arrays[0], 0);
081    for (T[] array : arrays) {
082      for (T t : array) result.add(t);
083    }
084    return result.toArray((T[]) Array.newInstance(tmp[0].getClass(), 0));
085  }
086
087  /**
088   * Format a string with size information about a map whose values are lists of elements.
089   * @param <T> the type of the keys in the map.
090   * @param <U> the type of the values in the map.
091   * @param name an arbitrary name given to the map.
092   * @param map the map from which to get size information.
093   * @return a string containing information about the number of elements in the map.
094   */
095  public static <T, U> String formatSizeMapInfo(final String name, final CollectionMap<T, U> map) {
096    StringBuilder sb = new StringBuilder();
097    sb.append(name).append("[shallow size=").append(map.size());
098    sb.append(", total elements=").append(map.size()).append(']');
099    return sb.toString();
100  }
101
102  /**
103   * Generate a list that contains the specified number of elements of the specified list,
104   * starting at the specified position in the specified list.
105   * @param <T> the type of the elements in the list.
106   * @param source the list from which to get the elements.
107   * @param start the start position in the source list.
108   * @param size the number of elements to get from the source list.
109   * @return the resulting list.
110   */
111  public static <T> List<T> getAllElements(final List<T> source, final int start, final int size) {
112    List<T> result = new ArrayList<>(size);
113    for (int i = 0; i < size; i++) result.add(source.get(i + start));
114    return result;
115  }
116
117  /**
118   * Return the parameters as an array.
119   * @param <T> the ytpe of the elements in the array. Inferred as the common supertype of all the elements.
120   * @param elts the elements of the array.
121   * @return an array of the specified type.
122   */
123  public static <T> T[] array(final T... elts) {
124    return elts;
125  }
126
127  /**
128   * Return the parameters as an array of Objects.
129   * @param elts the elements of the array.
130   * @return an array of <code>Object</code> instances.
131   */
132  public static Object[] objects(final Object... elts) {
133    return elts;
134  }
135
136  /**
137   * Print the content of a collection map in an easily readable way.
138   * @param map the map to print.
139   * @return a string with the map elements properly indented and formatted.
140   * @param <K> the type of the keys in the map.
141   * @param <V> the type of the values in the map.
142   */
143  public static <K, V> String prettyPrint(final CollectionMap<K, V> map) {
144    StringBuilder sb = new StringBuilder();
145    sb.append("{\n");
146    int count1 = 0;
147    for (K key : map.keySet()) {
148      if (count1 > 0) sb.append(",\n");
149      sb.append("  ").append(key).append(" = [\n");
150      int count2 = 0;
151      for (V value : map.getValues(key)) {
152        if (count2 > 0) sb.append(",\n");
153        sb.append("    ").append(value);
154        count2++;
155      }
156      sb.append("\n  ]");
157      count1++;
158    }
159    sb.append("\n}");
160    return sb.toString();
161  }
162}