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:ja@nuxeo.com">Julien Anguenot</a> 035 */ 036public final class ArrayUtils { 037 038 // This is an utility class. 039 private ArrayUtils() { 040 } 041 042 /** 043 * Merges any number of Array. 044 * <p> 045 * Comes from : http://forum.java.sun.com/thread.jspa?threadID=202127&messageID=676603 046 * 047 * @param arrays several arrays 048 * @return a merged array 049 */ 050 @SuppressWarnings("unchecked") 051 public static <T> T[] arrayMerge(T[]... arrays) { 052 int count = 0; 053 Class<?> klass = null; 054 for (T[] array : arrays) { 055 count += array.length; 056 if (klass == null && array.length > 0) { 057 klass = array[0].getClass(); 058 } 059 } 060 if (count == 0) { 061 // all arrays are empty, return the first one 062 return arrays[0]; 063 } 064 // create new array 065 T[] rv = (T[]) Array.newInstance(klass, count); 066 int start = 0; 067 for (T[] array : arrays) { 068 System.arraycopy(array, 0, rv, start, array.length); 069 start += array.length; 070 } 071 return rv; 072 } 073 074 /** 075 * Method for intersecting arrays elements. Copy of the first array and remove progressively elements if not found 076 * in the other arrays. 077 * <p> 078 * This method will keep the initial order of elements (as found in the first array). 079 */ 080 @SuppressWarnings("unchecked") 081 public static <T> T[] intersect(final T[]... arrays) { 082 final Class<?> type = arrays.getClass().getComponentType().getComponentType(); 083 if (arrays.length == 0) { 084 return (T[]) Array.newInstance(type, 0); 085 } 086 087 final List<T> commonItems = new ArrayList<>(); 088 089 final T[] firstArray = arrays[0]; 090 commonItems.addAll(Arrays.asList(firstArray)); 091 092 // check with the other arrays 093 // we skip the first array 094 for (int i = 1; i < arrays.length; i++) { 095 final T[] array = arrays[i]; 096 097 final List<T> arrayAsList = Arrays.asList(array); 098 099 final Set<T> itemsToRemove = new HashSet<>(); 100 for (T item : commonItems) { 101 if (!arrayAsList.contains(item)) { 102 itemsToRemove.add(item); 103 } 104 } 105 106 commonItems.removeAll(itemsToRemove); 107 } 108 109 T[] result = (T[]) Array.newInstance(type, commonItems.size()); 110 result = commonItems.toArray(result); 111 112 return result; 113 } 114 115}