001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nuxeo - initial API and implementation 018 * 019 * $Id: ArrayUtils.java 28607 2008-01-09 15:49:32Z sfermigier $ 020 */ 021 022package org.nuxeo.common.utils; 023 024import java.lang.reflect.Array; 025import java.util.ArrayList; 026import java.util.Arrays; 027import java.util.HashSet; 028import java.util.List; 029import java.util.Set; 030 031/** 032 * Array utils. 033 * 034 * @author <a href="mailto:[email protected]">Julien Anguenot</a> 035 */ 036@SuppressWarnings({ "SuppressionAnnotation" }) 037public final class ArrayUtils { 038 039 // This is an utility class. 040 private ArrayUtils() { 041 } 042 043 /** 044 * Merges any number of Array. 045 * <p> 046 * Comes from : http://forum.java.sun.com/thread.jspa?threadID=202127&messageID=676603 047 * 048 * @param arrays several arrays 049 * @return a merged array 050 */ 051 @SuppressWarnings("unchecked") 052 public static <T> T[] arrayMerge(T[]... arrays) { 053 int count = 0; 054 Class<?> klass = null; 055 for (T[] array : arrays) { 056 count += array.length; 057 if (klass == null && array.length > 0) { 058 klass = array[0].getClass(); 059 } 060 } 061 if (count == 0) { 062 // all arrays are empty, return the first one 063 return arrays[0]; 064 } 065 // create new array 066 T[] rv = (T[]) Array.newInstance(klass, count); 067 int start = 0; 068 for (T[] array : arrays) { 069 System.arraycopy(array, 0, rv, start, array.length); 070 start += array.length; 071 } 072 return rv; 073 } 074 075 /** 076 * Method for intersecting arrays elements. Copy of the first array and remove progressively elements if not found 077 * in the other arrays. 078 * <p> 079 * This method will keep the initial order of elements (as found in the first array). 080 */ 081 @SuppressWarnings("unchecked") 082 public static <T> T[] intersect(final T[]... arrays) { 083 final Class type = arrays.getClass().getComponentType().getComponentType(); 084 if (arrays.length == 0) { 085 return (T[]) Array.newInstance(type, 0); 086 } 087 088 final List<T> commonItems = new ArrayList<>(); 089 090 final T[] firstArray = arrays[0]; 091 commonItems.addAll(Arrays.asList(firstArray)); 092 093 // check with the other arrays 094 // we skip the first array 095 for (int i = 1; i < arrays.length; i++) { 096 final T[] array = arrays[i]; 097 098 final List<T> arrayAsList = Arrays.asList(array); 099 100 final Set<T> itemsToRemove = new HashSet<>(); 101 for (T item : commonItems) { 102 if (!arrayAsList.contains(item)) { 103 itemsToRemove.add(item); 104 } 105 } 106 107 commonItems.removeAll(itemsToRemove); 108 } 109 110 T[] result = (T[]) Array.newInstance(type, commonItems.size()); 111 result = commonItems.toArray(result); 112 113 return result; 114 } 115 116}