All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.function.ComparatorEx Maven / Gradle / Ivy

There is a newer version: 5.0-BETA-1
Show newest version
/*
 * Copyright (c) 2008-2021, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hazelcast.function;

import com.hazelcast.internal.util.ExceptionUtil;
import com.hazelcast.function.ComparatorsEx.NullComparator;

import java.io.Serializable;
import java.util.Comparator;
import java.util.function.Function;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;

import static com.hazelcast.internal.serialization.impl.SerializationUtil.checkSerializable;
import static com.hazelcast.internal.util.Preconditions.checkNotNull;

/**
 * {@code Serializable} variant of {@link Comparator java.util.Comparator}
 * which declares checked exception.
 *
 * @param  the type of objects that may be compared by this comparator
 *
 * @since 4.0
 */
@FunctionalInterface
@SuppressWarnings("checkstyle:methodcount")
public interface ComparatorEx extends Comparator, Serializable {

    /**
     * Exception-declaring version of {@link Comparator#compare}.
     * @throws Exception in case of any exceptional case
     */
    int compareEx(T o1, T o2) throws Exception;

    @Override
    default int compare(T o1, T o2) {
        try {
            return compareEx(o1, o2);
        } catch (Exception e) {
            throw ExceptionUtil.sneakyThrow(e);
        }
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#naturalOrder()
     * java.util.Comparator#naturalOrder()}.
     * @param   the {@link Comparable} type of element to be compared
     */
    @SuppressWarnings("unchecked")
    static > ComparatorEx naturalOrder() {
        return (ComparatorEx) ComparatorsEx.NATURAL_ORDER;
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#reverseOrder()
     * java.util.Comparator#reverseOrder()}.
     * @param   the {@link Comparable} type of element to be compared
     */
    @SuppressWarnings("unchecked")
    static > ComparatorEx reverseOrder() {
        return (ComparatorEx) ComparatorsEx.REVERSE_ORDER;
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#nullsFirst(Comparator)
     * java.util.Comparator#nullsFirst(Comparator)}.
     * @param   the type of the elements to be compared
     */
    static  ComparatorEx nullsFirst(Comparator comparator) {
        checkSerializable(comparator, "comparator");
        NullComparator c = new NullComparator<>(true);
        return comparator != null ? c.thenComparing(comparator) : c;
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#nullsFirst(Comparator)
     * java.util.Comparator#nullsFirst(Comparator)}.
     * @param   the type of the elements to be compared
     */
    static  ComparatorEx nullsFirst(ComparatorEx comparator) {
        return nullsFirst((Comparator) comparator);
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#nullsLast(Comparator)
     * java.util.Comparator#nullsLast(Comparator)}.
     * @param   the type of the elements to be compared
     */
    static  ComparatorEx nullsLast(Comparator comparator) {
        checkSerializable(comparator, "comparator");
        NullComparator c = new NullComparator<>(false);
        return comparator != null ? c.thenComparing(comparator) : c;
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#nullsLast(Comparator)
     * java.util.Comparator#nullsLast(Comparator)}.
     * @param   the type of the elements to be compared
     */
    static  ComparatorEx nullsLast(ComparatorEx comparator) {
        return nullsLast((Comparator) comparator);
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#comparing(Function, Comparator)
     * java.util.Comparator#comparing(Function, Comparator)}.
     * @param   the type of element to be compared
     * @param   the type of the sort key
     */
    static  ComparatorEx comparing(
            Function toKeyFn,
            Comparator keyComparator
    ) {
        checkNotNull(toKeyFn, "toKeyFn");
        checkNotNull(keyComparator, "keyComparator");
        checkSerializable(toKeyFn, "toKeyFn");
        checkSerializable(keyComparator, "keyComparator");
        return (c1, c2) -> keyComparator.compare(toKeyFn.apply(c1),
                toKeyFn.apply(c2));
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#comparing(Function, Comparator)
     * java.util.Comparator#comparing(Function, Comparator)}.
     * @param   the type of element to be compared
     * @param   the type of the sort key
     */
    static  ComparatorEx comparing(
            FunctionEx toKeyFn,
            ComparatorEx keyComparator) {
        return comparing((Function) toKeyFn, keyComparator);
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#comparing(Function)
     * java.util.Comparator#comparing(Function)}.
     * @param   the type of element to be compared
     * @param   the type of the {@code Comparable} sort key
     */
    static > ComparatorEx comparing(
            Function toKeyFn
    ) {
        checkNotNull(toKeyFn, "toKeyFn");
        checkSerializable(toKeyFn, "toKeyFn");
        return (left, right) -> toKeyFn.apply(left).compareTo(toKeyFn.apply(right));
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#comparing(Function)
     * java.util.Comparator#comparing(Function)}.
     * @param   the type of element to be compared
     * @param   the type of the {@code Comparable} sort key
     */
    static > ComparatorEx comparing(
            FunctionEx toKeyFn
    ) {
        return comparing((Function) toKeyFn);
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#comparingInt(ToIntFunction)
     * java.util.Comparator#comparingInt(ToIntFunction)}.
     * @param   the type of element to be compared
     */
    static  ComparatorEx comparingInt(ToIntFunction toKeyFn) {
        checkNotNull(toKeyFn, "toKeyFn");
        checkSerializable(toKeyFn, "toKeyFn");
        return (c1, c2) -> Integer.compare(toKeyFn.applyAsInt(c1), toKeyFn.applyAsInt(c2));
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#comparingInt(ToIntFunction)
     * java.util.Comparator#comparingInt(ToIntFunction)}.
     * @param   the type of element to be compared
     */
    static  ComparatorEx comparingInt(ToIntFunctionEx toKeyFn) {
        return comparingInt((ToIntFunction) toKeyFn);
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#comparingLong(ToLongFunction)
     * java.util.Comparator#comparingLong(ToLongFunction)}.
     * @param   the type of element to be compared
     */
    static  ComparatorEx comparingLong(ToLongFunction toKeyFn) {
        checkNotNull(toKeyFn, "toKeyFn");
        checkSerializable(toKeyFn, "toKeyFn");
        return (c1, c2) -> Long.compare(toKeyFn.applyAsLong(c1), toKeyFn.applyAsLong(c2));
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#comparingLong(ToLongFunction)
     * java.util.Comparator#comparingLong(ToLongFunction)}.
     * @param   the type of element to be compared
     */
    static  ComparatorEx comparingLong(ToLongFunctionEx toKeyFn) {
        return comparingLong((ToLongFunction) toKeyFn);
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#comparingDouble(ToDoubleFunction)
     * java.util.Comparator#comparingDouble(ToDoubleFunction)}.
     * @param   the type of element to be compared
     */
    static  ComparatorEx comparingDouble(ToDoubleFunction toKeyFn) {
        checkNotNull(toKeyFn, "toKeyFn");
        checkSerializable(toKeyFn, "toKeyFn");
        return (c1, c2) -> Double.compare(toKeyFn.applyAsDouble(c1), toKeyFn.applyAsDouble(c2));
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#comparingDouble(ToDoubleFunction)
     * java.util.Comparator#comparingDouble(ToDoubleFunction)}.
     * @param   the type of element to be compared
     */
    static  ComparatorEx comparingDouble(ToDoubleFunctionEx toKeyFn) {
        return comparingDouble((ToDoubleFunction) toKeyFn);
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#thenComparing(Comparator)
     * java.util.Comparator#thenComparing(Comparator)}.
     */
    @Override
    default ComparatorEx thenComparing(Comparator other) {
        checkNotNull(other, "other");
        checkSerializable(other, "other");
        return (c1, c2) -> {
            int res = compare(c1, c2);
            return (res != 0) ? res : other.compare(c1, c2);
        };
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#thenComparing(Comparator)
     * java.util.Comparator#thenComparing(Comparator)}.
     */
    default ComparatorEx thenComparing(ComparatorEx other) {
        return thenComparing((Comparator) other);
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#thenComparing(Function, Comparator)
     * java.util.Comparator#thenComparing(Function, Comparator)}.
     * @param    the type of the sort key
     */
    @Override
    default  ComparatorEx thenComparing(
            Function toKeyFn, Comparator keyComparator
    ) {
        checkSerializable(toKeyFn, "toKeyFn");
        checkSerializable(keyComparator, "keyComparator");
        return thenComparing(comparing(toKeyFn, keyComparator));
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#thenComparing(Function, Comparator)
     * java.util.Comparator#thenComparing(Function, Comparator)}.
     * @param    the type of the sort key
     */
    default  ComparatorEx thenComparing(
            FunctionEx toKeyFn,
            ComparatorEx keyComparator) {
        return thenComparing((Function) toKeyFn, keyComparator);
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#thenComparing(Function)
     * java.util.Comparator#thenComparing(Function)}.
     * @param    the type of the {@link Comparable} sort key
     */
    @Override
    default > ComparatorEx thenComparing(
            Function toKeyFn
    ) {
        checkSerializable(toKeyFn, "toKeyFn");
        return thenComparing(comparing(toKeyFn));
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#thenComparing(Function)
     * java.util.Comparator#thenComparing(Function)}.
     * @param    the type of the {@link Comparable} sort key
     */
    default > ComparatorEx thenComparing(
            FunctionEx toKeyFn) {
        return thenComparing((Function) toKeyFn);
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#thenComparingInt(ToIntFunction)
     * java.util.Comparator#thenComparingInt(ToIntFunction)}.
     */
    @Override
    default ComparatorEx thenComparingInt(ToIntFunction toKeyFn) {
        checkSerializable(toKeyFn, "toKeyFn");
        return thenComparing(comparingInt(toKeyFn));
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#thenComparingInt(ToIntFunction)
     * java.util.Comparator#thenComparingInt(ToIntFunction)}.
     */
    default ComparatorEx thenComparingInt(ToIntFunctionEx toKeyFn) {
        return thenComparingInt((ToIntFunction) toKeyFn);
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#thenComparingLong(ToLongFunction)
     * java.util.Comparator#thenComparingLong(ToLongFunction)}.
     */
    @Override
    default ComparatorEx thenComparingLong(ToLongFunction toKeyFn) {
        checkSerializable(toKeyFn, "toKeyFn");
        return thenComparing(comparingLong(toKeyFn));
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#thenComparingLong(ToLongFunction)
     * java.util.Comparator#thenComparingLong(ToLongFunction)}.
     */
    default ComparatorEx thenComparingLong(ToLongFunctionEx toKeyFn) {
        return thenComparingLong((ToLongFunction) toKeyFn);
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#thenComparingDouble(ToDoubleFunction)
     * java.util.Comparator#thenComparingDouble(ToDoubleFunction)}.
     */
    @Override
    default ComparatorEx thenComparingDouble(ToDoubleFunction toKeyFn) {
        checkSerializable(toKeyFn, "toKeyFn");
        return thenComparing(comparingDouble(toKeyFn));
    }

    /**
     * {@code Serializable} variant of {@link
     * Comparator#thenComparingDouble(ToDoubleFunction)
     * java.util.Comparator#thenComparingDouble(ToDoubleFunction)}.
     */
    default ComparatorEx thenComparingDouble(ToDoubleFunctionEx toKeyFn) {
        return thenComparingDouble((ToDoubleFunction) toKeyFn);
    }

    /**
     * {@code Serializable} variant of {@link Comparator#reversed()
     * java.util.Comparator#reversed()}
     */
    @Override
    default ComparatorEx reversed() {
        return (o1, o2) -> compare(o2, o1);
    }
}