changeset 8257:36add84c30fd

Move Functions.identity to Function (with workaround); garbage collect rest of Functions
author briangoetz
date Fri, 19 Apr 2013 14:15:50 -0400
parents 578fca17ae1d
children 960b36d46727
files src/share/classes/java/util/function/Function.java src/share/classes/java/util/function/Functions.java src/share/classes/java/util/stream/Collectors.java test-ng/bootlib/java/util/stream/LambdaTestHelpers.java test-ng/tests/org/openjdk/tests/java/util/regex/PatternTest.java test-ng/tests/org/openjdk/tests/java/util/stream/ForEachOpTest.java test-ng/tests/org/openjdk/tests/java/util/stream/GroupByOpTest.java test-ng/tests/org/openjdk/tests/java/util/stream/MapOpTest.java test-ng/tests/org/openjdk/tests/java/util/stream/ReduceByOpTest.java test-ng/tests/org/openjdk/tests/java/util/stream/SequentialOpTest.java test-ng/tests/org/openjdk/tests/java/util/stream/StreamBuilderTest.java test-ng/tests/org/openjdk/tests/java/util/stream/StreamSpliteratorTest.java test-ng/tests/org/openjdk/tests/java/util/stream/TabulatorsTest.java test/java/util/function/FunctionsTest.java
diffstat 14 files changed, 51 insertions(+), 361 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/function/Function.java	Fri Apr 19 10:54:36 2013 +0200
+++ b/src/share/classes/java/util/function/Function.java	Fri Apr 19 14:15:50 2013 -0400
@@ -80,4 +80,20 @@
         Objects.requireNonNull(after);
         return (T t) -> after.apply(apply(t));
     }
+
+    /**
+     * Returns a {@code Function} whose {@code apply} method returns its input.
+     * @param <T> The type of the input and output to the function
+     */
+    static <T> Function<T, T> identity() {
+        return Garbage.identity();
+    }
+
+    // @@@ Temporary garbage class as workaround for compiler bug with lambdas in static interface methods
+    // When fixed, inline Garbage.identity() into Function.identity and garbage-collect
+    class Garbage {
+        static <T> Function<T, T> identity() {
+            return t -> t;
+        }
+    }
 }
--- a/src/share/classes/java/util/function/Functions.java	Fri Apr 19 10:54:36 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.util.function;
-
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Static utility methods pertaining to {@code Function} instances.
- *
- * <p>All of the returned functions are serializable if provided serializable
- * parameters.
- */
-public final class Functions {
-
-    /**
-     * singleton utils
-     */
-    private Functions() {
-        throw new AssertionError("No instances!");
-    }
-
-     /**
-     * Returns a function whose {@code apply} method returns the provided
-     * input. Useful when a {@code Function<T,R>} is required and {@code <T>}
-     * and {@code <U>} are the same type.
-     */
-    public static <T> Function<T, T> identity() {
-        return t -> t;
-    }
-
-    /**
-     * Returns a constant output regardless of input.
-     *
-     * @param constant The value to be returned by the {@code apply} method
-     * @return a function whose {@code apply} method provides a constant result
-     */
-    public static <T, R> Function<T, R> constant(R constant) {
-        return t -> constant;
-    }
-
-    /**
-     * A function that substitutes a single input value with a specified
-     * replacement. Input values are compared using {@code equals()}.
-     *
-     * @param <T> The type of values
-     * @param subOut The input value to be substituted out
-     * @param subIn The replacement value for matching inputs
-     * @return a function that substitutes a single input value with a specified
-     * replacement.
-     */
-    public static <T> Function<T, T> substitute(T subOut, T subIn) {
-        return t -> Objects.equals(subOut, t) ? subIn : t;
-    }
-
-    /**
-     * Returns a function which maps inputs according to the provided mapping.
-     * Attempting to map a value not from the given map will cause an
-     * {@code IllegalArgumentException} to be thrown. A copy is
-     * <strong>not</strong> made of the map. Care should be taken to avoid
-     * changes to the map during use of the function.
-     *
-     * @param <T> input type to mapping function
-     * @param <R> output type from mapping function
-     * @param map provides mappings from {@code <T>} to {@code <R>}
-     * @throws NullPointerException if map is null
-     */
-    public static <R, T> Function<T, R> forMap(Map<? super T, ? extends R> map) {
-        Objects.requireNonNull(map);
-
-        return t -> {
-            // XXX mduigou it would be nice to optimise this to a single operation
-            if (map.containsKey(t)) {
-                return map.get(t);
-            } else {
-                throw new IllegalArgumentException("unmappable <T> : " + t);
-            }
-        };
-    }
-
-    /**
-     * Returns a function which maps inputs according to the provided mapping.
-     * The provided default value is returned for all {@code <T>} keys not found
-     * in the map. A copy is <strong>not</strong> made of the map. Care should
-     * be taken to avoid changes to the map during use of the function.
-     *
-     * @param <T> input type to mapping function
-     * @param <R> output type from mapping function
-     * @param <RR> type of values in the map
-     * @param map provides mappings from {@code <T>} to {@code <R>}
-     * @param defaultValue the value returned by {@code apply} method for
-     * {@code <T>} values not contained in the provided map.
-     * @throws NullPointerException if map is null
-     */
-    public static <T, R, RR extends R> Function<T, R> forMap(Map<? super T, RR> map, RR defaultValue) {
-        Objects.requireNonNull(map);
-
-        return t -> map.getOrDefault(t, defaultValue);
-    }
-
-    /**
-     * Map according to the provided predicate. Two output values are provided
-     * {@code forTrue} is returned if the predicate returns {@code true}
-     * otherwise the {@code forFalse} value is returned.
-     *
-     * @param <T> input type to mapping function
-     * @param <R> output type from mapping function
-     * @param predicate decides which value {@code apply} method should return
-     * @param forTrue value to be returned for {@code true} predicate results
-     * @param forFalse value to be returned for {@code false} predicate results
-     * @return a Function whose {@code apply} method provides results according to
-     * the provided predicate.
-     * @throws NullPointerException if predicate is null
-     */
-    public static <T, R> Function<T, R> forPredicate(Predicate<? super T> predicate, R forTrue, R forFalse) {
-        Objects.requireNonNull(predicate);
-
-        return t -> predicate.test(t) ? forTrue : forFalse;
-    }
-}
--- a/src/share/classes/java/util/stream/Collectors.java	Fri Apr 19 10:54:36 2013 +0200
+++ b/src/share/classes/java/util/stream/Collectors.java	Fri Apr 19 14:15:50 2013 -0400
@@ -913,7 +913,7 @@
      * @apiNote
      * It is common for either the key or the value to be the input elements.
      * In this case, the utility method
-     * {@link java.util.function.Functions#identity()} may be helpful.
+     * {@link java.util.function.Function#identity()} may be helpful.
      * For example, the following produces a {@code Map} mapping
      * students to their grade point average:
      * <pre>{@code
@@ -1046,7 +1046,7 @@
      * @apiNote
      * It is common for either the key or the value to be the input elements.
      * In this case, the utility method
-     * {@link java.util.function.Functions#identity()} may be helpful.
+     * {@link java.util.function.Function#identity()} may be helpful.
      * For example, the following produces a {@code Map} mapping
      * students to their grade point average:
      * <pre>{@code
--- a/test-ng/bootlib/java/util/stream/LambdaTestHelpers.java	Fri Apr 19 10:54:36 2013 +0200
+++ b/test-ng/bootlib/java/util/stream/LambdaTestHelpers.java	Fri Apr 19 14:15:50 2013 -0400
@@ -126,6 +126,12 @@
     public static final Function<String, IntStream> flattenInt
             = string -> Streams.intRange(0, string.length()).map(string::charAt);
 
+    public static <T, R> Function<T, R> forPredicate(Predicate<? super T> predicate, R forTrue, R forFalse) {
+        Objects.requireNonNull(predicate);
+
+        return t -> predicate.test(t) ? forTrue : forFalse;
+    }
+
     public static List<Integer> empty() {
         ArrayList<Integer> list = new ArrayList<>();
         list.add(null);
--- a/test-ng/tests/org/openjdk/tests/java/util/regex/PatternTest.java	Fri Apr 19 10:54:36 2013 +0200
+++ b/test-ng/tests/org/openjdk/tests/java/util/regex/PatternTest.java	Fri Apr 19 14:15:50 2013 -0400
@@ -5,15 +5,12 @@
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.function.Functions;
+import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.regex.Pattern;
 import java.util.stream.OpTestCase;
 import java.util.stream.Stream;
 import java.util.stream.StreamTestData;
-import java.util.stream.Streams;
-
-import static java.util.stream.Collectors.toList;
 
 @Test
 public class PatternTest extends OpTestCase {
@@ -100,6 +97,6 @@
     public void testStrings(String description, String input, Pattern pattern, List<String> expected) {
 	Supplier<Stream<String>> ss =  () -> pattern.splitAsStream(input);
 	withData(new StreamTestData.StreamSupplierData<>(description, ss))
-		 .stream(Functions.identity()).expectedResult(expected).exercise();
+		 .stream(Function.identity()).expectedResult(expected).exercise();
     }
 }
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/ForEachOpTest.java	Fri Apr 19 10:54:36 2013 +0200
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/ForEachOpTest.java	Fri Apr 19 14:15:50 2013 -0400
@@ -31,7 +31,6 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Function;
-import java.util.function.Functions;
 import java.util.stream.*;
 
 import static java.util.stream.LambdaTestHelpers.countTo;
@@ -80,7 +79,7 @@
 
         // Test multiple stages
         withData(data).
-                terminal(s -> s.map(Functions.identity()), terminalFunc).
+                terminal(s -> s.map(Function.identity()), terminalFunc).
                 expectedResult(input).
                 exercise();
     }
@@ -101,7 +100,7 @@
 
         // Test multiple stages
         withData(data).
-                terminal(s -> s.map(Functions.identity()), terminalFunc).
+                terminal(s -> s.map(Function.identity()), terminalFunc).
                 parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
                 exercise();
     }
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/GroupByOpTest.java	Fri Apr 19 10:54:36 2013 +0200
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/GroupByOpTest.java	Fri Apr 19 14:15:50 2013 -0400
@@ -33,9 +33,9 @@
 import java.util.Objects;
 import java.util.Set;
 import java.util.function.Function;
-import java.util.function.Functions;
 import java.util.stream.Collector;
 import java.util.stream.Collectors;
+import java.util.stream.LambdaTestHelpers;
 import java.util.stream.OpTestCase;
 import java.util.stream.Stream;
 import java.util.stream.StreamOpFlagTestHelper;
@@ -62,7 +62,7 @@
 
     public void testBypassCollect() {
         Collector<Integer, Map<Boolean, List<Integer>>> collector
-                = Collectors.groupingBy(Functions.forPredicate(pEven, true, false));
+                = Collectors.groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false));
 
         Map<Boolean, List<Integer>> m = collector.resultSupplier().get();
         int[] ints = countTo(10).stream().mapToInt(e -> (int) e).toArray();
@@ -83,7 +83,7 @@
     }
 
     public void testGroupBy() {
-        Map<Boolean,List<Integer>> result = countTo(10).stream().collect(Collectors.groupingBy(Functions.forPredicate(pEven, true, false)));
+        Map<Boolean,List<Integer>> result = countTo(10).stream().collect(Collectors.groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false)));
 
         assertEquals(2, result.keySet().size());
         for(Collection<Integer> group : result.values()) {
@@ -118,10 +118,10 @@
             new MapperData<>(mId.compose(mDoubler), uniqueSize),
             new MapperData<>(mDoubler.compose(mDoubler), uniqueSize),
 
-            new MapperData<>(Functions.forPredicate(pFalse, true, false), Math.min(1, uniqueSize)),
-            new MapperData<>(Functions.forPredicate(pTrue, true, false), Math.min(1, uniqueSize)),
-            new MapperData<>(Functions.forPredicate(pEven, true, false), Math.min(2, uniqueSize)),
-            new MapperData<>(Functions.forPredicate(pOdd, true, false), Math.min(2, uniqueSize))
+            new MapperData<>(LambdaTestHelpers.forPredicate(pFalse, true, false), Math.min(1, uniqueSize)),
+            new MapperData<>(LambdaTestHelpers.forPredicate(pTrue, true, false), Math.min(1, uniqueSize)),
+            new MapperData<>(LambdaTestHelpers.forPredicate(pEven, true, false), Math.min(2, uniqueSize)),
+            new MapperData<>(LambdaTestHelpers.forPredicate(pOdd, true, false), Math.min(2, uniqueSize))
         );
     }
 
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/MapOpTest.java	Fri Apr 19 10:54:36 2013 +0200
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/MapOpTest.java	Fri Apr 19 14:15:50 2013 -0400
@@ -28,7 +28,7 @@
 
 import java.util.function.DoubleToIntFunction;
 import java.util.function.DoubleToLongFunction;
-import java.util.function.Functions;
+import java.util.function.Function;
 import java.util.function.IntToDoubleFunction;
 import java.util.function.IntToLongFunction;
 import java.util.function.LongToDoubleFunction;
@@ -56,8 +56,8 @@
         assertCountSum(countTo(10).stream().map(mDoubler), 10, 110);
         assertCountSum(countTo(10).stream().map(mDoubler).map(mDoubler), 10, 220);
 
-        exerciseOps(countTo(0), s -> s.map(Functions.identity()), countTo(0));
-        exerciseOps(countTo(1000), s -> s.map(Functions.identity()), countTo(1000));
+        exerciseOps(countTo(0), s -> s.map(Function.identity()), countTo(0));
+        exerciseOps(countTo(1000), s -> s.map(Function.identity()), countTo(1000));
         // @@@ Force cast to integer so output is Stream<Integer> rather an IntStream
         //     this just ensures that no warnings are logged about boxing
         //     when the result is compared with the output
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/ReduceByOpTest.java	Fri Apr 19 10:54:36 2013 +0200
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/ReduceByOpTest.java	Fri Apr 19 14:15:50 2013 -0400
@@ -25,6 +25,7 @@
 package org.openjdk.tests.java.util.stream;
 
 import java.util.List;
+import java.util.stream.LambdaTestHelpers;
 import java.util.stream.OpTestCase;
 import java.util.stream.StreamTestData;
 import java.util.stream.StreamTestDataProvider;
@@ -32,7 +33,6 @@
 
 import java.util.HashSet;
 import java.util.Map;
-import java.util.function.Functions;
 
 import static java.util.stream.Collectors.groupingBy;
 import static java.util.stream.Collectors.reducing;
@@ -48,8 +48,8 @@
 
     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
     public void testOps(String name, StreamTestData<Integer> data) {
-        Map<Boolean,List<Integer>> gbResult = data.stream().collect(groupingBy(Functions.forPredicate(pEven, true, false)));
-        Map<Boolean, Integer> result = data.stream().collect(groupingBy(Functions.forPredicate(pEven, true, false), reducing(0, rPlus)));
+        Map<Boolean,List<Integer>> gbResult = data.stream().collect(groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false)));
+        Map<Boolean, Integer> result = data.stream().collect(groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false), reducing(0, rPlus)));
         assertEquals(result.size(), gbResult.size());
         for (Map.Entry<Boolean, Integer> entry : result.entrySet()) {
             Boolean key = entry.getKey();
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/SequentialOpTest.java	Fri Apr 19 10:54:36 2013 +0200
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/SequentialOpTest.java	Fri Apr 19 14:15:50 2013 -0400
@@ -24,7 +24,6 @@
  */
 package org.openjdk.tests.java.util.stream;
 
-import java.util.function.Functions;
 import java.util.stream.LambdaTestHelpers;
 import java.util.stream.OpTestCase;
 import java.util.stream.StreamTestData;
@@ -53,7 +52,7 @@
     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
           groups = { "serialization-hostile" })
     public void testLazy(String name, StreamTestData<Integer> data) {
-        Function<Integer, Integer> id = Functions.identity();
+        Function<Integer, Integer> id = Function.identity();
         AtomicInteger counter = new AtomicInteger();
         Supplier<Stream<Integer>>[] suppliers = new Supplier[] { () -> data.stream(), () -> data.parallelStream() };
         UnaryOperator<Stream<Integer>>[] configs
@@ -94,7 +93,7 @@
     @SuppressWarnings({"rawtypes", "unchecked"})
     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
     public void testMixedSeqPar(String name, StreamTestData<Integer> data) {
-        Function<Integer, Integer> id = Functions.identity();
+        Function<Integer, Integer> id = Function.identity();
         UnaryOperator<Stream<Integer>>[] changers
                 = new UnaryOperator[] {
                 (UnaryOperator<Stream<Integer>>) s -> s,
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/StreamBuilderTest.java	Fri Apr 19 10:54:36 2013 +0200
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/StreamBuilderTest.java	Fri Apr 19 14:15:50 2013 -0400
@@ -31,7 +31,6 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.function.Function;
-import java.util.function.Functions;
 import java.util.stream.DoubleStream;
 import java.util.stream.DoubleStreamTestData;
 import java.util.stream.IntStream;
@@ -88,7 +87,7 @@
                 exercise();
 
         withData(data).
-                stream(s -> s.map(Functions.identity())).
+                stream(s -> s.map(Function.identity())).
                 expectedResult(Collections.singletonList(1)).
                 exercise();
     }
@@ -132,7 +131,7 @@
                 exercise();
 
         withData(data).
-                stream(s -> s.map(Functions.identity())).
+                stream(s -> s.map(Function.identity())).
                 expectedResult(Streams.intRange(0, size).boxed().collect(toList())).
                 exercise();
     }
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/StreamSpliteratorTest.java	Fri Apr 19 10:54:36 2013 +0200
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/StreamSpliteratorTest.java	Fri Apr 19 14:15:50 2013 -0400
@@ -31,7 +31,6 @@
 import java.util.function.Consumer;
 import java.util.function.DoubleConsumer;
 import java.util.function.Function;
-import java.util.function.Functions;
 import java.util.function.IntConsumer;
 import java.util.function.LongConsumer;
 import java.util.function.UnaryOperator;
@@ -258,7 +257,7 @@
         List<UnaryOperator<Stream<Integer>>> intermediateOps = Arrays.asList(
                 s -> s.parallel(),
                 // The following ensures the wrapping spliterator is tested
-                s -> s.map(Functions.identity()).parallel()
+                s -> s.map(Function.identity()).parallel()
         );
 
         for (Consumer<Stream<Integer>> terminalOp : terminalOps) {
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/TabulatorsTest.java	Fri Apr 19 10:54:36 2013 +0200
+++ b/test-ng/tests/org/openjdk/tests/java/util/stream/TabulatorsTest.java	Fri Apr 19 14:15:50 2013 -0400
@@ -37,7 +37,6 @@
 import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.function.BinaryOperator;
 import java.util.function.Function;
-import java.util.function.Functions;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
 import java.util.stream.Collector;
@@ -321,23 +320,23 @@
         exerciseMapTabulation(data,
                               groupingBy(classifier, reducing(0, Integer::sum)),
                               new GroupedMapAssertion<>(classifier, HashMap.class,
-                                                        new ReduceAssertion<>(0, Functions.identity(), Integer::sum)));
+                                                        new ReduceAssertion<>(0, Function.identity(), Integer::sum)));
         // with concurrent
         exerciseMapTabulation(data,
                               groupingByConcurrent(classifier, reducing(0, Integer::sum)),
                               new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class,
-                                                        new ReduceAssertion<>(0, Functions.identity(), Integer::sum)));
+                                                        new ReduceAssertion<>(0, Function.identity(), Integer::sum)));
 
         // With explicit constructors
         exerciseMapTabulation(data,
                               groupingBy(classifier, TreeMap::new, reducing(0, Integer::sum)),
                               new GroupedMapAssertion<>(classifier, TreeMap.class,
-                                                        new ReduceAssertion<>(0, Functions.identity(), Integer::sum)));
+                                                        new ReduceAssertion<>(0, Function.identity(), Integer::sum)));
         // with concurrent
         exerciseMapTabulation(data,
                               groupingByConcurrent(classifier, ConcurrentSkipListMap::new, reducing(0, Integer::sum)),
                               new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class,
-                                                        new ReduceAssertion<>(0, Functions.identity(), Integer::sum)));
+                                                        new ReduceAssertion<>(0, Function.identity(), Integer::sum)));
 
         // Single-level map-reduce
         exerciseMapTabulation(data,
@@ -390,6 +389,6 @@
         exerciseMapTabulation(data,
                               partitioningBy(classifier, reducing(0, Integer::sum)),
                               new PartitionAssertion<>(classifier,
-                                                       new ReduceAssertion<>(0, Functions.identity(), Integer::sum)));
+                                                       new ReduceAssertion<>(0, Function.identity(), Integer::sum)));
     }
 }
--- a/test/java/util/function/FunctionsTest.java	Fri Apr 19 10:54:36 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test Basic test for Functions functional utils
- * @run testng FunctionsTest
- */
-
-import java.lang.reflect.UndeclaredThrowableException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-import java.util.function.IntFunction;
-import java.util.function.Functions;
-
-import org.testng.annotations.Test;
-
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.fail;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-
-/*
- * Basic test for Functions functional utils
- */
-public class FunctionsTest {
-    private static final Function<Boolean, Boolean> fFalse = x -> false;
-
-    @Test
-    public void testIdentity() {
-        String str0 = null;
-        String str1 = "null";
-        String str2 = "";
-        assertNull(Functions.identity().apply(null));
-        assertEquals(FunctionsTest.class, Functions.identity().apply(FunctionsTest.class));
-        assertEquals(Functions.identity().apply(str0), str0);
-        assertEquals(Functions.identity().apply(str1), str1);
-        assertEquals(Functions.identity().apply(str2), str2);
-    }
-
-    @Test
-    public void testToString() {
-        assertEquals("null", ((Function<Object,String>)String::valueOf).apply(null));
-        assertEquals("1", ((Function<Object,String>)String::valueOf).apply(1));
-        assertEquals("surprise!", ((Function<Object,String>)String::valueOf).apply(new Object() {
-            public String toString() {return "surprise!";}
-        }));
-    }
-
-    @Test
-    public void testConstant() {
-        List<String> l = new ArrayList<>(10);
-        l.add(null);
-        l.add("test");
-        assertEquals(FunctionsTest.class, Functions.constant(FunctionsTest.class).apply(null));
-        assertEquals(FunctionsTest.class, Functions.constant(FunctionsTest.class).apply("1"));
-        assertEquals(Functions.constant(null).apply(false), null);
-        assertEquals(Functions.constant(new ArrayList<>()).apply(l).size(), 0);
-        assertEquals(Functions.constant(l).apply("test").size(), 2);
-    }
-
-    public static class Goomba {
-        public final int value;
-        public Goomba(Integer x) {
-            value = x;
-        }
-    }
-
-    @Test
-    public void testInstantiate() {
-        IntFunction<Integer> f = Integer::valueOf;
-
-        assertEquals(1, f.apply(1).intValue());
-        assertEquals(2, f.apply(2).intValue());
-    }
-
-    @Test
-    public void testForPredicate() {
-        Function<Integer, String> mapper = Functions.forPredicate(x -> x != 0, "true", "false");
-
-        assertEquals("false", mapper.apply(0));
-        assertEquals("true", mapper.apply(1));
-    }
-
-    @Test
-    public void testForMap() {
-        Map<Integer, String> truths = new HashMap<>();
-        truths.put(0, "sky");
-        truths.put(1, "ice");
-
-        Function<Integer, String> mapper = Functions.forMap(truths);
-
-        assertEquals("sky", mapper.apply(0));
-        assertEquals("ice", mapper.apply(1));
-        THROWS(IllegalArgumentException.class, () -> {String result = mapper.apply(999); assert false;});
-    }
-
-    @Test
-    public void testForMapDefault() {
-        Map<Integer, String> truths = new HashMap<>();
-        truths.put(0, "sky");
-        truths.put(1, "ice");
-
-        Function<Integer, String> mapper = Functions.forMap(truths, "fire");
-
-        assertEquals("sky", mapper.apply(0));
-        assertEquals("ice", mapper.apply(1));
-        assertEquals("fire", mapper.apply(999));
-        assertEquals("fire", mapper.apply(Integer.MAX_VALUE));
-    }
-
-    @Test
-    public void testSubstitute() {
-        Function<Integer, Integer> ints = Functions.substitute(3, 999);
-        Function<String, String> strings = Functions.substitute("hello", "bonjour");
-        Function<String, String> stringNullIn = Functions.substitute(null, "default");
-        Function<String, String> stringNullOut = Functions.substitute("default", null);
-
-        assertEquals(1, (int) ints.apply(1));
-        assertEquals(999, (int) ints.apply(3));
-        assertEquals("gutentag", strings.apply("gutentag"));
-        assertEquals("bonjour", strings.apply("hello"));
-        assertEquals("gutentag", stringNullIn.apply("gutentag"));
-        assertEquals("default", stringNullIn.apply(null));
-        assertEquals("gutentag", stringNullOut.apply("gutentag"));
-        assertEquals(null, stringNullOut.apply("default"));
-    }
-
-    @Test(expectedExceptions = {NullPointerException.class})
-    void testForPredicateNPE() {
-        @SuppressWarnings("unchecked")
-        Function<Boolean, Boolean> f = Functions.forPredicate(null, true, false);
-        boolean result = f.apply(true);
-    }
-
-    @Test(expectedExceptions = {IllegalArgumentException.class})
-    void testForMapNullIAE() {
-        @SuppressWarnings("unchecked")
-        Map<String, Integer> m = new HashMap<>();
-        for (int i = 0; i < 10; i++) {
-                m.put(String.valueOf(i), new Integer(i));
-        }
-        Function<String, Integer> f = Functions.forMap(m);
-        int result = f.apply(null);
-    }
-
-    public interface Fun {void f() throws Throwable;}
-
-    void THROWS(Class<? extends Throwable> k, Fun... fs) {
-        for (Fun f : fs)
-            try {
-                f.f();
-                fail("Expected " + k.getName() + " not thrown");
-            } catch (Throwable t) {
-                if (!k.isAssignableFrom(t.getClass()))
-                    throw new UndeclaredThrowableException(t);
-            }
-    }
-}