Re: Multidimensional arrays and arrays of arrays
Patricia Shanahan wrote:
public static boolean isArrayOfArrays(Object x){
Class<? extends Object> xClass = x.getClass();
Isn't "extends Object" redundant? The upper bound of all wildcards is
always Object.
I just happened to be writing some code similar to what the OP is asking
about. I was playing around with "Java lamda functions" and wanted to
see if I could make a method take any type of array, Collection, or Map.
The following code is presented without further comment, just as an
example to inspire thought.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package evaluator;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Eval1
{
/**
* @param args the command line arguments
*/
public static void main( String[] args ) throws LamdaException
{
Evaluater<Double> evalPlus3 = new Evaluater<Double>()
{
@Override
public Double eval( Double o )
{
return o + 3.0;
}
};
Evaluater<Object> evalPrintln = new Evaluater<Object>()
{
@Override
public Void eval( Object o ) {
System.out.println( o );
return null;
}
};
EvaluaterTransform<Double,String> evalFmt = new
EvaluaterTransform<Double,String>() {
@Override
public String eval( Double d ) {
return String.format( "%06.2g", d );
}
};
EvaluaterAggregation<Double,String> fmtString =
new EvaluaterAggregation<Double,String>() {
StringBuilder sb = new StringBuilder();
public void eval( Double o )
{
sb.append( String.format( "%06.2g", o));
}
public String getResult()
{
return sb.toString();
}
};
double[] dArray = {1.2, 2.3, 3.4};
ArrayList<Double> dAL = new ArrayList<Double>();
dAL.add( 4.5 );
dAL.add( 5.6 );
HashMap<String, Double> sdHM = new HashMap<String, Double>();
sdHM.put( "one", 6.7 );
sdHM.put( "two", 7.8 );
System.out.println( Arrays.toString( (double[]) lamda( dArray,
evalPlus3 ) ) );
System.out.println( lamda( dAL, evalPlus3 ) );
System.out.println( lamda( sdHM, evalPlus3 ) );
lamda( lamda(dArray, evalPlus3), evalPrintln );
lamda( lamda(dArray, evalFmt), evalPrintln );
// TODO car, cdr
// lamdaFirst, lamdaSkipFirst ?
// new class LamdaList which supports cdr car functions?
}
public static Object lamda( Object array, EvaluaterTransform ev )
throws
LamdaException
{
if( !array.getClass().isArray() &&
!array.getClass().getComponentType().
isPrimitive() ) {
throw new LamdaException( "Object must be primitive array,
was " +
array.getClass().getName() );
}
Object retValue = Array.newInstance( Object.class, Array.getLength(
array ) );
if( int.class == array.getClass().getComponentType() ) {
for( int i = 0; i < Array.getLength( array ); i++ ) {
Array.set( retValue, i, ev.eval( Array.getInt( array, i
) ) );
}
} else if( double.class == array.getClass().getComponentType() ) {
for( int i = 0; i < Array.getLength( array ); i++ ) {
Array.set( retValue, i, ev.eval( Array.getDouble(
array, i ) ) );
}
}
return retValue;
}
public static Object lamda( Object o, Evaluater ev ) throws
LamdaException
{
Object retval = null;
if( o.getClass().isArray() ) {
Class<?> arrayElementClass = o.getClass().getComponentType();
Object newArray = Array.newInstance( arrayElementClass, Array.
getLength( o ) );
if( !arrayElementClass.isPrimitive() ) {
for( int i = 0; i < Array.getLength( o ); i++ ) {
Array.set( newArray, i, ev.eval( Array.get( o, i ) ) );
}
}
else if( double.class == arrayElementClass ) {
for( int i = 0; i < Array.getLength( o ); i++ ) {
Object result = ev.eval( Array.getDouble( o, i ) );
if( result != null ) {
Array.setDouble( newArray, i, (Double) ev.eval(
Array.
getDouble( o, i ) ) );
} else
{
Array.setDouble( newArray, i, 0.0 );
}
}
}
else if( int.class == arrayElementClass ) {
for( int i = 0; i < Array.getLength( o ); i++ ) {
Array.setInt( newArray, i, (Integer) ev.eval(
Array.getInt( o, i ) ) );
}
}
retval = newArray;
}
else if( o instanceof Collection ) {
Collection<?> input = (Collection<?>) o;
try {
Collection<Object> newCollection =
(Collection<Object>) o.getClass().newInstance();
for( Object value : input ) {
newCollection.add( ev.eval( value ) );
}
retval = newCollection;
}
catch( InstantiationException ex ) {
// Logger.getLogger( Evaluator.class.getName() ).
// log( Level.SEVERE, null, ex );
throw new LamdaCollectionInstanteationException( "class=" +
o.getClass().getName(), ex );
}
catch( IllegalAccessException ex ) {
// Logger.getLogger( Evaluator.class.getName() ).
// log( Level.SEVERE, null, ex );
throw new LamdaCollectionInstanteationException( "class=" +
o.getClass().getName(), ex );
}
}
else if( o instanceof Map ) {
Map input = (Map) o;
try {
Map newMap = input.getClass().newInstance();
Set<Map.Entry> keySet = input.entrySet();
for( Map.Entry key : keySet ) {
Object result = ev.eval( key.getValue() );
newMap.put( key.getKey(), result );
}
retval = newMap;
}
catch( InstantiationException ex ) {
// Logger.getLogger( Evaluator.class.getName() ).
// log( Level.SEVERE, null, ex );
throw new LamdaMapInstanteationException( "class=" +
o.getClass().getName(), ex );
}
catch( IllegalAccessException ex ) {
// Logger.getLogger( Evaluator.class.getName() ).
// log( Level.SEVERE, null, ex );
throw new LamdaMapInstanteationException( "class=" +
o.getClass().getName(), ex );
}
}
return retval;
}
}
interface Evaluater<T>
{
public T eval( T o );
// public Class<T> getType();
}
interface EvaluaterAggregation<T,U>
{
public void eval( T o );
public U getResult();
// public Class<T> getEvalType();
// public Class<U> getResultType();
}
interface EvaluaterTransform<T,U>
{
public U eval( T t );
// public Class<T> getEvalType();
// public Class<U> getReturnType();
}
class LamdaException extends Exception
{
public LamdaException( Throwable cause )
{
super( cause );
}
public LamdaException( String message, Throwable cause )
{
super( message, cause );
}
public LamdaException( String message )
{
super( message );
}
public LamdaException()
{
}
}
class LamdaMapInstanteationException extends LamdaException
{
public LamdaMapInstanteationException()
{
}
public LamdaMapInstanteationException( String message )
{
super( message );
}
public LamdaMapInstanteationException( String message, Throwable
cause )
{
super( message, cause );
}
public LamdaMapInstanteationException( Throwable cause )
{
super( cause );
}
}
class LamdaCollectionInstanteationException extends LamdaException
{
public LamdaCollectionInstanteationException()
{
}
public LamdaCollectionInstanteationException( String message )
{
super( message );
}
public LamdaCollectionInstanteationException( String message,
Throwable cause )
{
super( message, cause );
}
public LamdaCollectionInstanteationException( Throwable cause )
{
super( cause );
}
}
abstract class LamdaList implements Cloneable, Serializable
{
public LamdaListObject newLamdaList( Object [] o )
{
return new LamdaListObject( o );
}
public abstract LamdaList lamda( Evaluater e );
public abstract double [] asDoubleArray();
public abstract int [] asIntArray();
public abstract LamdaList first();
public abstract void first( Evaluater e );
public abstract LamdaList skipFirst();
public abstract void skipFirst( Evaluater e );
public abstract boolean isPrimitive();
public abstract boolean isPrimitiveDouble();
public abstract boolean isPrimitiveInt();
@Override
public abstract String toString();
@Override
public abstract Object clone();
}
//class LamdaListObject extends LamdaList
class LamdaListObject
{
Object [] oArray;
LamdaListObject( Object[] o ){
oArray = o;
}
}