// List-based generic reduction - Page 123 package org.effectivejava.examples.chapter05.item25; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Reduction { static <E> E reduce(List<E> list, Function<E> f, E initVal) { List<E> snapshot; synchronized (list) { snapshot = new ArrayList<E>(list); } E result = initVal; for (E e : snapshot) result = f.apply(result, e); return result; } // A few sample functions private static final Function<Integer> SUM = new Function<Integer>() { public Integer apply(Integer i1, Integer i2) { return i1 + i2; } }; private static final Function<Integer> PRODUCT = new Function<Integer>() { public Integer apply(Integer i1, Integer i2) { return i1 * i2; } }; private static final Function<Integer> MAX = new Function<Integer>() { public Integer apply(Integer i1, Integer i2) { return Math.max(i1, i2); } }; private static final Function<Integer> MIN = new Function<Integer>() { public Integer apply(Integer i1, Integer i2) { return Math.min(i1, i2); } }; public static void main(String[] args) { List<Integer> intList = Arrays.asList(2, 7, 1, 8, 2, 8, 1, 8, 2, 8); // Reduce intList using each of the above reducers System.out.println(reduce(intList, SUM, 0)); System.out.println(reduce(intList, PRODUCT, 1)); System.out.println(reduce(intList, MAX, Integer.MIN_VALUE)); System.out.println(reduce(intList, MIN, Integer.MAX_VALUE)); } }