/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.utils.datastructures; import java.io.PrintStream; import java.lang.reflect.Array; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.NoSuchElementException; /** * Multi-dimension array utils. * * @See {@link Array} related * @See {@link Arrays} related * @See {@link Collections} related * @author Toni Kalajainen (toni.kalajainen@vtt.fi) */ public class MultiDimensionArrayUtils { /** * Print multi-dimension array * @param o */ public static void printArrayDeep(Object v, PrintStream out) { ArrayIterator i = arrayIterator(v, getArrayLengths(v)); while (i.hasNext()) System.out.println(Arrays.toString(i.getIndices())+" = "+i.next()); } /** * Get array length of each dimension of a multi-dimension array. * * @param value multi-dimension array * @return lengths of each dimension */ public static int[] getArrayLengths(Object value) { int dim = getDimension(value.getClass()); int result[] = new int[ dim ]; if (dim==0) return result; Object o = value; for (int i=0; i clazz) { String signature = clazz.getName(); int dim = 0; for (; dim componentType, int[] dims) { // Java 1.6.0 return (Object[]) Array.newInstance(componentType, dims); /* // Older than 1.6.0 if (dims==null || componentType==null || dims.length==0) throw new IllegalArgumentException(); if (dims.length==1) return Array.newInstance(componentType, dims[0]); int[][] dimArrays = new int[dims.length][]; dimArrays[0] = dims; for (int j=1; j componentType, int[][] dimArrays, int lvl) { int[] dims = dimArrays[lvl]; int len = dims[0]; Object[] result = (Object[]) Array.newInstance(componentType, dims); if (lvl getComponentType(Class clazz) { Class result = clazz; while (result.isArray()) result = result.getComponentType(); return result; } /** * Demux single-dimension array (x[]) to a multi-dimension array (x[][][]) * * @param src single-dimension array * @param dims * @return multi-dimension array */ public static Object demuxArray(Object src, int[] dims) { return demuxArray(src, dims, getComponentType(src.getClass())); } /** * Demux single-dimension array (x[]) to a multi-dimension array (x[][][]) * * @param src single-dimension array * @param dims * @param componentType * @return multi-dimension array */ public static Object demuxArray(Object src, int[] dims, Class componentType) { Object dst = Array.newInstance(componentType, dims); _fillDemux(0, dims, src, 0, dst); return dst; } /** * Demuxes single dimension array into a multi-dimension array * * @param src one dimension array (e.g. int[]) * @param dimensions length of each dimension * @param dst multi-dimension array to be filled (use createMultiDimArray()) */ public static void demuxArray(Object src, int[] dims, Object dst) { if (Array.getLength(src) != getLength(dims)) throw new IllegalArgumentException("The length of src does not match the length of dst"); _fillDemux(0, dims, src, 0, dst); } private static int _fillDemux(int lvl, int[] dims, Object src, int srcIndex, Object dst) { // lower level if (lvl==dims.length-1) { int len = dims[dims.length-1]; System.arraycopy(src, srcIndex, dst, 0, len); return srcIndex + len; } // higher level for (int i=0; i componentType) { int len = getLength(dims); Object dst = Array.newInstance(componentType, len); muxArray(src, dims, dst); return dst; } /** * Multiplexes multi-dimension array into a single-dimension array * * @param src multi-dimension array * @param dims dimensions * @param dst single-dimension array */ public static void muxArray(Object src, int[] dims, Object dst) { int len = getLength(dims); if (Array.getLength(dst) != len) throw new IllegalArgumentException("The length of src does not match the length of dst"); _fillMux(0, dims, src, dst, 0); } private static int _fillMux(int lvl, int[] dims, Object src, Object dst, int dstIndex) { if (lvl == dims.length-1) { int len = dims[lvl]; System.arraycopy(src, 0, dst, dstIndex, len); return dstIndex + len; } for (int i=0; i ArrayIterator arrayIterator(Object array, int[] dimLens) { return new ArrayIterator(array, dimLens); } public static class ArrayIterator implements Iterator { Object v; int[] dims; int[] indices; Object[] arrays; int lastIndex, len; boolean hasNext = true; ArrayIterator(Object array, int[] dimLens) { this.v = array; this.dims = dimLens; this.indices = new int[dimLens.length]; this.arrays = new Object[dimLens.length]; lastIndex = dimLens.length-1; @SuppressWarnings("unused") int len = dimLens[0]; for (int i=0; i<=lastIndex; i++) if (dimLens[i]==0) hasNext = false; for (int i=1; i<=lastIndex; i++) len *= dimLens[i]; arrays[0] = (Object[]) v; for (int i=1; i= dims[index]) { indices[index] = 0; index--; if (index<0) { hasNext = false; return; } arrays[index+1] = ((Object[]) arrays[index])[indices[index]]; } if (index