import java.util.*; class G18 { static interface UnaryFunction<S,T> { T apply( S arg ); } public static <T,S> List<T> map( List<S> list, UnaryFunction<? super S, ? extends T> fun ){ List<T> result = new ArrayList<T>(list.size()); for( S s: list ){ result.add( fun.apply(s) ); } return result; } static interface BinaryOperator<T> { T apply( T arg1, T arg2 ); } static class IntegerAddition implements BinaryOperator<Integer> { public Integer apply( Integer a, Integer b){ return a+b; } } static class IntegerMaximum implements BinaryOperator<Integer> { public Integer apply( Integer a, Integer b){ return a < b ? b : a; } } public static <T> T fold( List<T> list, T start, BinaryOperator<T> op ){ T result = start; for( T t: list ){ result = op.apply(result,t); } return result; } public static <T> LinkedList<T> flatten( List<List<? extends T>> listOfLists ){ LinkedList<T> list = new LinkedList<T>(); for( List<? extends T> aList: listOfLists ){ list.addAll(aList); } return list; } public static void main( String[] args ){ List<Integer> numbers = map( fromArrayToList(args), new UnaryFunction<String,Integer>(){ public Integer apply(String s){ return new Integer(s); } } ); System.out.println(numbers); int sum = fold( numbers, 0, new IntegerAddition() ); System.out.println(sum); System.out.println( fold(numbers, numbers.get(0), new IntegerMaximum()) ); } public static <T> ArrayList<T> fromArrayToList( T[] a ){ ArrayList<T> list = new ArrayList<T>(a.length); for( T o: a ){ list.add(o); } return list; } public static <T,S> void map( Collection<T> dest, Collection<S> src, UnaryFunction<? super S, ? extends T> fun ){ for( S s: src ){ dest.add( fun.apply(s) ); } } public static <T> void flatten( Collection<T> dest, Collection<Collection<? extends T>> src ){ for( Collection<? extends T> c: src ){ dest.addAll(c); } } }