/* * Copyright (c) 2012, 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. */ /** * @summary This class provide basic support for lambda syntax * @(#) LambdaUtilities.java * @author Tristan Yan */ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; import java.nio.file.Path; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.function.*; import java.util.stream.IntStream; import java.util.stream.Stream; public class LambdaUtilities { public static enum CharType { DIGIT, LOWERCASE, UPPERCASE, SPECIAL } public static enum StringPredicateType { START_WTIH, NOT_START_WITH, MORE_THAN_LEN, LESS_THAN_LEN } public static enum IntOp { ADD, SUBTRACT, MULTIPLY, DIVIDE, MOD } public static IntPredicate randomIntPredicate(boolean isUP, int limit) { if (isUP) { return i -> i >= limit; } else { return i -> i < limit; } } public static Predicate randomIntegerPredicate(boolean isUP, int limit) { if (isUP) { return i -> i >= limit; } else { return i -> i < limit; } } public static LongPredicate randomLongPredicate(boolean isUP, long limit) { if (isUP) { return i -> i >= limit; } else { return i -> i < limit; } } public static Predicate startPathPredicate(Path start) { return p -> p.startsWith(start); } public static Predicate randomGenericPredicate(boolean isUp, T value, Comparator c) { if (isUp) { return emp -> c.compare(emp, value) >= 0; }else { return emp -> c.compare(emp, value) < 0; } } public static Predicate randomSBPredicate(StringPredicateType type, String value) { switch (type) { case START_WTIH: return sb -> Character.isDigit(sb.charAt(0)); case NOT_START_WITH: return sb -> Character.isLowerCase(sb.charAt(0)); case MORE_THAN_LEN: return sb -> Character.isUpperCase(sb.charAt(0)); default: return sb -> !Character.isLetterOrDigit(sb.charAt(0)); } } public static Predicate randomSBPredicate(CharType startType, boolean first) { switch (startType) { case DIGIT: return sb -> Character.isDigit(sb.charAt(first ? 0 : sb.toString().length() - 1)); case LOWERCASE: return sb -> Character.isLowerCase(sb.charAt(first ? 0 : sb.toString().length() - 1)); case UPPERCASE: return sb -> Character.isUpperCase(sb.charAt(first ? 0 : sb.toString().length() - 1)); default: return sb -> !Character.isLetterOrDigit(sb.charAt(first ? 0 : sb.toString().length() - 1)); } } public static Predicate isDigitCharacterPredicate() { return c -> Character.isDigit(c); } public static Function posIntegerFunction(boolean isHighest) { if (isHighest) { return i -> Integer.valueOf(new StringBuilder().append(i < 0 ? -i : i).reverse().toString()) % 10; } else { return i -> i % 10 < 0 ? -i % 10 : i % 10; } } public static Function sbGenericFunction(boolean isFirst) { if (isFirst) return i -> Character.isAlphabetic(i.charAt(0)) ? (Character.isUpperCase(i.charAt(0)) ? CharType.UPPERCASE : CharType.LOWERCASE) : (Character.isDigit(i.charAt(0)) ? CharType.DIGIT : CharType.SPECIAL); else return i -> Character.isAlphabetic(i.charAt(i.length() - 1)) ? (Character.isUpperCase(i.charAt(i.length() - 1)) ? CharType.UPPERCASE : CharType.LOWERCASE) : (Character.isDigit(i.charAt(i.length() - 1)) ? CharType.DIGIT : CharType.SPECIAL); } public static Function mappingFunction(Map m, IntOp op, int value) { switch (op) { case ADD: return k -> (value != 0) ? m.get(k) + value : m.get(k); case SUBTRACT: return k -> (value != 0) ? m.get(k) - value : m.get(k); case MULTIPLY: return k -> (value != 0) ? m.get(k) * value : m.get(k); case DIVIDE: return k -> (value != 0) ? m.get(k) / value : m.get(k); default: return k -> (value != 0) ? m.get(k) % value : m.get(k); } } public static IntFunction posIntFunction(boolean isHighest) { if (isHighest) { return i -> Integer.valueOf(new StringBuilder().append(i < 0 ? -i : i).reverse().toString()) % 10; } else { return i -> i % 10 < 0 ? -i % 10 : i % 10; } } public static BiFunction randBetweenIntegerFunction() { return (t1, t2) -> randBetween(t1, t2); } public static int randBetween(int low, int up) { assert (low < up && low >= 0); Random rand = new Random(); int i = rand.nextInt(up); while (i < low) { i = rand.nextInt(); } return i; } public static ToIntFunction highestPosValueIntFunction() { return i -> Integer.valueOf(new StringBuilder().append(i < 0 ? -i : i).reverse().toString()) % 10; } public static ToIntFunction lowestPosValueIntFunction() { return i -> i % 10 < 0 ? -i % 10 : i % 10; } public static Consumer reverseConsumer(Set set) { return t -> { set.add(t); }; } public static Consumer addIntegerConsumer(AtomicInteger ai) { return t -> { ai.updateAndGet(t1 -> t1 + t); }; } public static Consumer appendSBConsumer(StringBuilder sb) { return t -> { sb.append(t); }; } public static IntConsumer addIntConsumer(AtomicInteger ai) { return t -> { ai.updateAndGet(t1 -> t1 + t); }; } public static IntConsumer addLongConsumer(AtomicLong ai) { return t -> { ai.updateAndGet(t1 -> t1 + t); }; } public static Consumer copyConsumer(List list) { return t -> { list.add(t); }; } public static Consumer existsConsumer(Collection in, Collection out) { return t -> { if (in.contains(t)) { out.add(t); } }; } public static Supplier sbSupplier(StringBuilder value) { return () -> value; } public static Supplier integerSupplier(int value) { return () -> value; } public static Supplier genericSuppiler(T value) { return () -> value; } public static IntSupplier intSupplier(int value) { return () -> value; } public static Supplier longSupplier(long value) { return () -> value; } public static Supplier atomicIntegerSupplier(int value) { return () -> new AtomicInteger(value); } public static Supplier> atomicGenericSupplier(T value) { return () -> new AtomicReference<>(value); } public static Supplier> atomicSBSupplier(StringBuilder value) { return () -> new AtomicReference<>(value); } public static UnaryOperator opIntegerUnaryOperator(IntOp op, int value) { switch (op) { case ADD: return t -> t + value; case SUBTRACT: return t -> t - value; case MULTIPLY: return t -> t * value; case DIVIDE: return t -> t / value; default: return t -> t % value; } } public static IntUnaryOperator opIntUnaryOperator(IntOp op, int value) { if(value == 0) return t -> t; switch (op) { case ADD: return t -> t + value; case SUBTRACT: return t -> t - value; case MULTIPLY: return t -> t * value; case DIVIDE: return t -> t / value; default: return t -> t % value; } } public static Function opIntegerFunction(IntOp op, int value) { if(value == 0) return t -> t; switch (op) { case ADD: return t -> Integer.valueOf(t + value); case SUBTRACT: return t -> Integer.valueOf(t - value); case MULTIPLY: return t -> Integer.valueOf(t * value); case DIVIDE: return t -> Integer.valueOf(t / value); default: return t -> Integer.valueOf(t % value); } } public static ToIntFunction opToIntFunction(IntOp op, int value) { if(value == 0) return t -> t.intValue(); switch (op) { case ADD: return t -> t.intValue() + value; case SUBTRACT: return t -> t.intValue() - value; case MULTIPLY: return t -> t.intValue() * value; case DIVIDE: return t -> t.intValue() / value; default: return t -> t.intValue() % value; } } public static IntFunction opIntFunction(IntOp op, int value) { if(value == 0) return t -> t; switch (op) { case ADD: return t -> t + value; case SUBTRACT: return t -> t - value; case MULTIPLY: return t -> t * value; case DIVIDE: return t -> t / value; default: return t -> t % value; } } public static IntUnaryOperator addIntUnaryOperator(int value) { return t -> t + value; } public static IntUnaryOperator subIntUnaryOperator(int value) { return t -> t - value; } public static IntUnaryOperator mulIntUnaryOperator(int value) { return t -> t * value; } public static IntUnaryOperator divIntUnaryOperator(int value) { return t -> t / value; } public static IntBinaryOperator minIntBinaryOperator() { return (t1, t2) -> t1< t2 ? t1 : t2; } public static BinaryOperator minIntegerBinaryOperator(Comparator c) { return (t1, t2) -> c.compare(t1, t2) < 0 ? t1 : t2; } public static BinaryOperator minGenericBinaryOperator(Comparator c) { return (t1, t2) -> c.compare(t1, t2) < 0 ? t1 : t2; } public static BinaryOperator minSBBinaryOperator(Comparator c) { return ( t1, t2 ) -> c.compare(t1, t2) < 0 ? t1 : t2; } public static IntBinaryOperator maxIntBinaryOperator() { return ( t1, t2 ) -> (t1< t2) ? t2: t1; } public static BinaryOperator maxIntegerBinaryOperator(Comparator c) { return (t1, t2) -> c.compare(t1, t2) < 0 ? t2 : t1; } public static BinaryOperator maxGenericBinaryOperator(Comparator c) { return (t1, t2) -> c.compare(t1, t2) < 0 ? t2 : t1; } public static IntBinaryOperator maxIntBinaryOperator(Comparator c) { return ( t1, t2 ) -> c.compare(t1, t2) < 0 ? t2 : t1; } public static BinaryOperator maxSBBinaryOperator(Comparator c) { return ( t1, t2 ) -> c.compare(t1, t2) < 0 ? t2 : t1; } public static BinaryOperator addIntegerBinaryOperator() { return ( t1 , t2 ) -> t1 + t2; } public static IntBinaryOperator addIntBinaryOperator() { return ( t1 , t2 ) -> t1 + t2; } public static BinaryOperator addBigDecimalBinaryOperator() { return ( t1 , t2 ) -> t1.add(t2); } public static DoubleBinaryOperator addDoubleBinaryOperator() { return ( t1 , t2 ) -> t1 + t2; } public static BinaryOperator appendSBBinaryOperator() { return (t1 , t2) -> new StringBuilder().append(t1).append(t2); } public static BinaryOperator subIntegerBinaryOperator() { return (t1, t2) -> t1 - t2; } public static IntBinaryOperator subIntBinaryOperator() { return (t1, t2) -> t1 - t2; } public static BinaryOperator deleteSBBinaryOperator() { return (t1, t2) -> {if (t1.length() >= t2.length()) { int i1 = t1.indexOf(t2.toString()); int i2 = i1 + t2.length(); return new StringBuilder(t1).delete(i1, i2); }else { int i1 = t2.indexOf(t1.toString()); int i2 = i1 + t1.length(); return new StringBuilder(t2).delete(i1, i2); } }; } public static IntBinaryOperator mulIntBinaryOperator() { return (t1, t2) -> t1 * t2; } public static IntBinaryOperator divIntBinaryOperator() { return (t1, t2) -> t1 / t2; } public static LongUnaryOperator addLongUnaryOperator(long value) { return t -> t + value; } public static UnaryOperator appendSBUnaryOperator(StringBuilder value) { return t -> t.append(value); } public static LongUnaryOperator subLongUnaryOperator(long value) { return t -> t - value; } public static LongUnaryOperator mulLongUnaryOperator(long value) { return t -> t * value; } public static LongUnaryOperator divLongUnaryOperator(long value) { return t -> t / value; } public static LongBinaryOperator addLongBinaryOperator() { return (t1, t2) -> t1 + t2; } public static LongBinaryOperator subLongBinaryOperator() { return (t1, t2) -> t1 - t2; } public static LongBinaryOperator mulLongBinaryOperator() { return (t1, t2) -> t1 * t2; } public static LongBinaryOperator divLongBinaryOperator() { return (t1, t2) -> t1 / t2; } public static BiConsumer addIntegerBiConsumer() { return (t1 , t2 ) -> { t1.addAndGet(t2); }; } public static BiConsumer addAtomicIntegerBiConsumer() { return (t1 , t2) -> { t1.addAndGet(t2.get()); }; } public static BiConsumer, StringBuilder> appendSBBiConsumer() { return (t1, t2) -> {t1.updateAndGet(appendSBUnaryOperator(t2));}; } public static BiConsumer, AtomicReference> appendAtomicSBBiConsumer() { return (t1, t2) -> {t1.updateAndGet(appendSBUnaryOperator(t2.get()));}; } public static BiConsumer maxIntegerBiConsumer(Comparator c) { return (t1 , t2 ) -> { t1.getAndUpdate(t -> max(t, t2, c)); }; } public static BiConsumer, T> maxGenericBiConsumer(Comparator c) { return (t1 , t2 ) -> { t1.getAndUpdate(t -> max(t, t2, c)); }; } public static BiConsumer maxAtomicIntegerBiConsumer(Comparator c) { return (t1 , t2) -> { t1.getAndUpdate(t -> max(t, t2.get(), c)); }; } public static BiConsumer, AtomicReference> maxAtomicGenericBiConsumer(Comparator c) { return (t1 , t2) -> { t1.getAndUpdate(t -> max(t, t2.get(), c)); }; } public static BiConsumer minIntegerBiConsumer(Comparator c) { return (t1 , t2) -> { t1.getAndUpdate(t -> min(t, t2, c)); }; } public static BiConsumer, T> minGenericBiConsumer(Comparator c) { return (t1 , t2) -> { t1.getAndUpdate(t -> min(t, t2, c)); }; } public static BiConsumer minAtomicIntegerBiConsumer(Comparator c) { return (t1, t2) -> { t1.getAndUpdate(t -> min(t, t2.get(), c)); }; } public static BiConsumer, AtomicReference> minAtomicGenericBiConsumer(Comparator c) { return (t1, t2) -> { t1.getAndUpdate(t -> min(t, t2.get(), c)); }; } public static BiFunction maxIntegerFunction(Comparator c) { return (t1, t2) -> max(t1, t2, c); } public static BiFunction deviationSequareFunction(double avg) { return (bd, t) -> bd.add(new BigDecimal(avg - t).pow(2)); } public static BiFunction maxGenericFunction(Comparator c) { return (t1, t2) -> max(t1, t2, c); } public static BiFunction maxStringBuilderFunction(Comparator c) { return (t1, t2) -> max(t1, t2, c); } public static BiFunction minIntegerFunction(Comparator c) { return (t1, t2) -> min(t1, t2, c); } public static BiFunction minGenericFunction(Comparator c) { return (t1, t2) -> min(t1, t2, c); } public static BiFunction minStringBuilderFunction(Comparator c) { return (t1, t2) -> min(t1, t2, c); } public static BiFunction opBiFunction(IntOp op, int value) { switch (op) { case ADD: return (k, v) -> (value != 0) ? v + value : v; case SUBTRACT: return (k, v) -> (value != 0) ? v - value : v; case MULTIPLY: return (k, v) -> (value != 0) ? v * value : v; case DIVIDE: return (k, v) -> (value != 0) ? v / value : v; default: return (k, v) -> (value != 0) ? v % value : v; } } public static BiFunction opBiFunction(IntOp op) { switch (op) { case ADD: return (oldv, v) -> (v != 0) ? oldv + v : oldv; case SUBTRACT: return (oldv, v) -> (v != 0) ? oldv - v : oldv; case MULTIPLY: return (oldv, v) -> (v != 0) ? oldv * v : oldv; case DIVIDE: return (oldv, v) -> (v != 0) ? oldv / v : oldv; default: return (oldv, v) -> (v != 0) ? oldv % v : oldv; } } private static Integer min(Integer i1, Integer i2, Comparator c) { return c.compare(i1, i2) < 0 ? i1 : i2; } private static T min(T i1, T i2, Comparator c) { return c.compare(i1, i2) < 0 ? i1 : i2; } private static StringBuilder min(StringBuilder sb1, StringBuilder sb2, Comparator c) { return c.compare(sb1, sb2) < 0 ? sb1 : sb2; } private static Integer max(Integer i1, Integer i2, Comparator c) { return c.compare(i1, i2) < 0 ? i2 : i1; } private static T max(T i1, T i2, Comparator c) { return c.compare(i1, i2) < 0 ? i2 : i1; } private static StringBuilder max(StringBuilder sb1, StringBuilder sb2, Comparator c) { return c.compare(sb1, sb2) < 0 ? sb2 : sb1; } /* * Construct a Collection C object based on a C object, using generic type * instead of Class type can help preventing type error in compilation */ @SuppressWarnings({"rawtypes", "unchecked"}) public static > C create(C c, int... initSize) throws InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { return create((Class) c.getClass(), initSize); } /* * Construct a Collection C object based on a C's type, using generic type * instead of Class type can help preventing type error in compilation */ @SuppressWarnings({"rawtypes", "unchecked"}) public static > T create( Class> cls, int... initSize) throws InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { assert (initSize.length <= 1); Collection c; if (initSize.length == 0) { c = cls.newInstance(); } else { Constructor con = cls.getConstructor(int.class); c = (Collection) con.newInstance(initSize[0]); } return (T) c; } /* * Construct a T object based on T's type, using generic type instead of * Class type can help preventing type error in compilation */ @SuppressWarnings({"rawtypes", "unchecked"}) public static > M createMap(M m, int... initSize) throws InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { return createMap((Class) m.getClass(), initSize); } /* * Construct a Map M object based on M's type, using generic type instead of * Class type can help preventing type error in compilation */ @SuppressWarnings({"rawtypes", "unchecked"}) public static > M createMap(Class> cls, int... initSize) throws InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { assert (initSize.length <= 1); Map map; if (initSize.length == 0) { map = cls.newInstance(); } else { Constructor con = cls.getConstructor(int.class); map = (Map) con.newInstance(initSize[0]); } return (M) map; } }