Comparators entry point with generically typed factory methods
Issue: SPR-14779
This commit is contained in:
@@ -21,12 +21,12 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.comparator.ComparableComparator;
|
||||
import org.springframework.util.comparator.Comparators;
|
||||
|
||||
/**
|
||||
* A {@link Comparator} that converts values before they are compared. The specified
|
||||
* {@link Converter} will be used to convert each value before it passed to the underlying
|
||||
* {@code Comparator}.
|
||||
* A {@link Comparator} that converts values before they are compared.
|
||||
* The specified {@link Converter} will be used to convert each value
|
||||
* before it passed to the underlying {@code Comparator}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 3.2
|
||||
@@ -44,9 +44,8 @@ public class ConvertingComparator<S, T> implements Comparator<S> {
|
||||
* Create a new {@link ConvertingComparator} instance.
|
||||
* @param converter the converter
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConvertingComparator(Converter<S, T> converter) {
|
||||
this(ComparableComparator.INSTANCE, converter);
|
||||
this(Comparators.comparable(), converter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +61,7 @@ public class ConvertingComparator<S, T> implements Comparator<S> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link ComparableComparator} instance.
|
||||
* Create a new {@code ConvertingComparator} instance.
|
||||
* @param comparator the underlying comparator
|
||||
* @param conversionService the conversion service
|
||||
* @param targetType the target type
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,23 +20,24 @@ import java.io.Serializable;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* A Comparator for Boolean objects that can sort either true or false first.
|
||||
* A {@link Comparator} for {@link Boolean} objects that can sort either
|
||||
* {@code true} or {@code false} first.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 1.2.2
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public final class BooleanComparator implements Comparator<Boolean>, Serializable {
|
||||
public class BooleanComparator implements Comparator<Boolean>, Serializable {
|
||||
|
||||
/**
|
||||
* A shared default instance of this comparator, treating true lower
|
||||
* than false.
|
||||
* A shared default instance of this comparator,
|
||||
* treating {@code true} lower than {@code false}.
|
||||
*/
|
||||
public static final BooleanComparator TRUE_LOW = new BooleanComparator(true);
|
||||
|
||||
/**
|
||||
* A shared default instance of this comparator, treating true higher
|
||||
* than false.
|
||||
* A shared default instance of this comparator,
|
||||
* treating {@code true} higher than {@code false}.
|
||||
*/
|
||||
public static final BooleanComparator TRUE_HIGH = new BooleanComparator(false);
|
||||
|
||||
@@ -64,20 +65,16 @@ public final class BooleanComparator implements Comparator<Boolean>, Serializabl
|
||||
return (v1 ^ v2) ? ((v1 ^ this.trueLow) ? 1 : -1) : 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof BooleanComparator)) {
|
||||
return false;
|
||||
}
|
||||
return (this.trueLow == ((BooleanComparator) obj).trueLow);
|
||||
return (this == obj ||
|
||||
(obj instanceof BooleanComparator && (this.trueLow == ((BooleanComparator) obj).trueLow)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (this.trueLow ? -1 : 1) * getClass().hashCode();
|
||||
return getClass().hashCode() * (this.trueLow ? -1 : 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,9 +29,14 @@ import java.util.Comparator;
|
||||
*/
|
||||
public class ComparableComparator<T extends Comparable<T>> implements Comparator<T> {
|
||||
|
||||
/**
|
||||
* A shared instance of this default comparator
|
||||
* @see Comparators#comparable()
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static final ComparableComparator INSTANCE = new ComparableComparator();
|
||||
|
||||
|
||||
@Override
|
||||
public int compare(T o1, T o2) {
|
||||
return o1.compareTo(o2);
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.util.comparator;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Convenient entry point with generically typed factory methods
|
||||
* for common Spring {@link Comparator} variants.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 5.0
|
||||
*/
|
||||
public abstract class Comparators {
|
||||
|
||||
/**
|
||||
* Return a {@link Comparable} adapter.
|
||||
* @see ComparableComparator#INSTANCE
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Comparator<T> comparable() {
|
||||
return ComparableComparator.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link Comparable} adapter which accepts
|
||||
* null values and sorts them lower than non-null values.
|
||||
* @see NullSafeComparator#NULLS_LOW
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Comparator<T> nullsLow() {
|
||||
return NullSafeComparator.NULLS_LOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a decorator for the given comparator which accepts
|
||||
* null values and sorts them lower than non-null values.
|
||||
* @see NullSafeComparator#NullSafeComparator(boolean)
|
||||
*/
|
||||
public static <T> Comparator<T> nullsLow(Comparator<T> comparator) {
|
||||
return new NullSafeComparator<T>(comparator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link Comparable} adapter which accepts
|
||||
* null values and sorts them higher than non-null values.
|
||||
* @see NullSafeComparator#NULLS_HIGH
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Comparator<T> nullsHigh() {
|
||||
return NullSafeComparator.NULLS_HIGH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a decorator for the given comparator which accepts
|
||||
* null values and sorts them higher than non-null values.
|
||||
* @see NullSafeComparator#NullSafeComparator(boolean)
|
||||
*/
|
||||
public static <T> Comparator<T> nullsHigh(Comparator<T> comparator) {
|
||||
return new NullSafeComparator<T>(comparator, false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,7 +36,10 @@ import org.springframework.util.Assert;
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.2.2
|
||||
* @deprecated as of Spring Framework 5.0, in favor of the standard JDK 8
|
||||
* {@link Comparator#thenComparing(Comparator)}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings({"serial", "rawtypes"})
|
||||
public class CompoundComparator<T> implements Comparator<T>, Serializable {
|
||||
|
||||
@@ -165,10 +168,11 @@ public class CompoundComparator<T> implements Comparator<T>, Serializable {
|
||||
return this.comparators.size();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public int compare(T o1, T o2) {
|
||||
Assert.state(this.comparators.size() > 0,
|
||||
Assert.state(!this.comparators.isEmpty(),
|
||||
"No sort definitions have been added to this CompoundComparator to compare");
|
||||
for (InvertibleComparator comparator : this.comparators) {
|
||||
int result = comparator.compare(o1, o2);
|
||||
@@ -179,6 +183,7 @@ public class CompoundComparator<T> implements Comparator<T>, Serializable {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,12 +27,12 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* <p>Only the specified {@code instanceOrder} classes are considered during comparison.
|
||||
* If two objects are both instances of the ordered type this comparator will return a
|
||||
* {@code 0}. Consider combining with a {@link CompoundComparator} if additional sorting
|
||||
* is required.
|
||||
* {@code 0}. Consider combining with {@link Comparator#thenComparing(Comparator)}
|
||||
* if additional sorting is required.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 3.2
|
||||
* @see CompoundComparator
|
||||
* @see Comparator#thenComparing(Comparator)
|
||||
* @param <T> the type of objects being compared
|
||||
*/
|
||||
public class InstanceComparator<T> implements Comparator<T> {
|
||||
@@ -46,7 +46,7 @@ public class InstanceComparator<T> implements Comparator<T> {
|
||||
* objects. Classes earlier in the list will be given a higher priority.
|
||||
*/
|
||||
public InstanceComparator(Class<?>... instanceOrder) {
|
||||
Assert.notNull(instanceOrder, "'instanceOrder' must not be null");
|
||||
Assert.notNull(instanceOrder, "'instanceOrder' array must not be null");
|
||||
this.instanceOrder = instanceOrder;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,7 +29,10 @@ import org.springframework.util.Assert;
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.2.2
|
||||
* @deprecated as of Spring Framework 5.0, in favor of the standard JDK 8
|
||||
* {@link Comparator#reversed()}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("serial")
|
||||
public class InvertibleComparator<T> implements Comparator<T>, Serializable {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,6 +34,7 @@ public class NullSafeComparator<T> implements Comparator<T> {
|
||||
/**
|
||||
* A shared default instance of this comparator, treating nulls lower
|
||||
* than non-null objects.
|
||||
* @see Comparators#nullsLow()
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static final NullSafeComparator NULLS_LOW = new NullSafeComparator<>(true);
|
||||
@@ -41,10 +42,12 @@ public class NullSafeComparator<T> implements Comparator<T> {
|
||||
/**
|
||||
* A shared default instance of this comparator, treating nulls higher
|
||||
* than non-null objects.
|
||||
* @see Comparators#nullsHigh()
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static final NullSafeComparator NULLS_HIGH = new NullSafeComparator<>(false);
|
||||
|
||||
|
||||
private final Comparator<T> nonNullComparator;
|
||||
|
||||
private final boolean nullsLow;
|
||||
@@ -64,9 +67,9 @@ public class NullSafeComparator<T> implements Comparator<T> {
|
||||
* @see #NULLS_LOW
|
||||
* @see #NULLS_HIGH
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes"})
|
||||
@SuppressWarnings("unchecked")
|
||||
private NullSafeComparator(boolean nullsLow) {
|
||||
this.nonNullComparator = new ComparableComparator();
|
||||
this.nonNullComparator = ComparableComparator.INSTANCE;
|
||||
this.nullsLow = nullsLow;
|
||||
}
|
||||
|
||||
@@ -80,7 +83,7 @@ public class NullSafeComparator<T> implements Comparator<T> {
|
||||
* @param nullsLow whether to treat nulls lower or higher than non-null objects
|
||||
*/
|
||||
public NullSafeComparator(Comparator<T> comparator, boolean nullsLow) {
|
||||
Assert.notNull(comparator, "The non-null comparator is required");
|
||||
Assert.notNull(comparator, "Non-null Comparator is required");
|
||||
this.nonNullComparator = comparator;
|
||||
this.nullsLow = nullsLow;
|
||||
}
|
||||
@@ -100,6 +103,7 @@ public class NullSafeComparator<T> implements Comparator<T> {
|
||||
return this.nonNullComparator.compare(o1, o2);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean equals(Object obj) {
|
||||
@@ -115,7 +119,7 @@ public class NullSafeComparator<T> implements Comparator<T> {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (this.nullsLow ? -1 : 1) * this.nonNullComparator.hashCode();
|
||||
return this.nonNullComparator.hashCode() * (this.nullsLow ? -1 : 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user