/** * Given a list of objects, determines the right comparator to use. * If all elements are numbers, use special comparator which treats all numeric wrapper types the same. * Otherwise use default "natural" comparator. * Validates that all elements are comparable as well as numbers and non-numbers aren't mixed together. * @param values List of values * @param caller the calling Class (for better context in error reporting) * @return either {@link com.glassdoor.planout4j.planout.ops.utils.MixedNumbersComparator} or * {@link org.apache.commons.collections4.ComparatorUtils#NATURAL_COMPARATOR} */ @SuppressWarnings("unchecked") public static Comparator<Object> getComparator(final List<Object> values, final Class caller) { boolean useMixedNumbersComparator = false; for (Object value : values) { if (value instanceof Number) { useMixedNumbersComparator = true; } else { checkState(value == null || value instanceof Comparable, "%s: non-comparable object of type %s", caller, getClassName(value)); checkState(!useMixedNumbersComparator, "%s: mixed numbers / not numbers array, can't compare", caller); } } return useMixedNumbersComparator ? MixedNumbersComparator.INSTANCE : ComparatorUtils.NATURAL_COMPARATOR; }
private TreeMultimap<ContentType, BaseContent> getTopNRelevantBeans(int _numResult) { TreeMultimap<ContentType, BaseContent> retVal = TreeMultimap.create(ComparatorUtils.NATURAL_COMPARATOR, BaseContent.CONTENT_COMPARATOR); for (Map.Entry<ContentType, Collection<BaseContent>> beansByType : getContentBeansByType().entrySet()) { List<BaseContent> sortedValues = new ArrayList<BaseContent>(beansByType.getValue()); Collections.sort(sortedValues, (Comparator<? super BaseContent>) BaseContent.CONTENT_COMPARATOR); if (sortedValues.size() > _numResult) { sortedValues.subList(_numResult, sortedValues.size()).clear(); // trim to top 2 from each kind } retVal.putAll(beansByType.getKey(), sortedValues); } return retVal; }
@Override public TreeMultimap<BaseContent.ContentType, DocumentMeta> getEntityMeta(Collection<String> _metaIdentifiers, ResultsType _resultsType) throws DatastoreException { TreeMultimap<BaseContent.ContentType, DocumentMeta> retVal = TreeMultimap.create(ComparatorUtils.NATURAL_COMPARATOR, DocumentMeta.DOCUMENT_META_COMPARATOR); for (String metaIdentifier : _metaIdentifiers) { Collection<DocumentMeta> entityMeta = getEntityMeta(metaIdentifier, _resultsType); if (!CollectionUtils.isEmpty(entityMeta)) { BaseContent.ContentType key = ContentDictionary.getContentType(metaIdentifier); retVal.putAll(key, getEntityMeta(metaIdentifier, _resultsType)); } } return retVal; }
/** * Test select rejected predicate. */ @Test public void testSelectRejectedPredicate(){ Predicate<Integer> predicate = new ComparatorPredicate<Integer>(10, ComparatorUtils.<Integer> naturalComparator(), Criterion.LESS); List<Integer> result = CollectionsUtil.selectRejected(toList(1, 5, 10, 30, 55, 88, 1, 12, 3), predicate); assertThat(result, contains(1, 5, 10, 1, 3)); }
/** * Test select predicate. */ @Test public void testSelectPredicate(){ //查询 >10 的元素 Predicate<Integer> predicate = new ComparatorPredicate<Integer>(10, ComparatorUtils.<Integer> naturalComparator(), Criterion.LESS); List<Integer> result = CollectionsUtil.select(toList(1, 5, 10, 30, 55, 88, 1, 12, 3), predicate); assertThat(result, contains(30, 55, 88, 12)); }
@Test public void testComparatorPredicate1(){ User user = new User(2L); assertEquals( false, BeanPredicateUtil.comparatorPredicate("id", 5L, ComparatorUtils.<Long> naturalComparator(), Criterion.LESS) .evaluate(user)); }
@Test public void testPropertyComparatorWithTreeSetWithComparable(){ UserSameHashCodeWithComparable userSameHashCodeWithComparable1 = new UserSameHashCodeWithComparable(1, "11"); UserSameHashCodeWithComparable userSameHashCodeWithComparable2 = new UserSameHashCodeWithComparable(5, "2"); //------ PropertyComparator<UserSameHashCodeWithComparable> propertyComparator = new PropertyComparator<>("name"); assertThat(propertyComparator.compare(userSameHashCodeWithComparable1, userSameHashCodeWithComparable2), lessThan(0)); propertyComparator = new PropertyComparator<>("name", Integer.class, ComparatorUtils.NATURAL_COMPARATOR); assertEquals(1, propertyComparator.compare(userSameHashCodeWithComparable1, userSameHashCodeWithComparable2)); }
/** * Test equal predicate null property name. */ @Test(expected = NullPointerException.class) public void testComparatorPredicateNullPropertyName(){ BeanPredicateUtil.comparatorPredicate((String) null, 5, ComparatorUtils.<Integer> naturalComparator(), Criterion.LESS); }
/** * Test equal predicate empty property name. */ @Test(expected = IllegalArgumentException.class) public void testComparatorPredicateEmptyPropertyName(){ BeanPredicateUtil.comparatorPredicate("", 5, ComparatorUtils.<Integer> naturalComparator(), Criterion.LESS); }
/** * Test equal predicate blank property name. */ @Test(expected = IllegalArgumentException.class) public void testComparatorPredicateBlankPropertyName(){ BeanPredicateUtil.comparatorPredicate("", 5, ComparatorUtils.<Integer> naturalComparator(), Criterion.LESS); }
/** * Test sort array null array. */ @Test public void testSortArrayNullArray(){ String[] arrays = null; assertEquals(EMPTY_STRING_ARRAY, sortArray(arrays, ComparatorUtils.<String> naturalComparator())); }
@Test(expected = NullPointerException.class) public void testPropertyComparatorNullPropertyNameAndNaturalComparator(){ new PropertyComparator<>(null, ComparatorUtils.NATURAL_COMPARATOR); }
@Test(expected = IllegalArgumentException.class) public void testPropertyComparatorEmptyPropertyNameAndNaturalComparator(){ new PropertyComparator<>("", ComparatorUtils.NATURAL_COMPARATOR); }
@Test(expected = IllegalArgumentException.class) public void testPropertyComparatorBlankPropertyNameAndNaturalComparator(){ new PropertyComparator<>(" ", ComparatorUtils.NATURAL_COMPARATOR); }
@Test(expected = NullPointerException.class) public void testPropertyComparatorNullPropertyNameAndPropertyValueConvertToClassAndNaturalComparator(){ new PropertyComparator<>(null, Integer.class, ComparatorUtils.NATURAL_COMPARATOR); }
@Test(expected = IllegalArgumentException.class) public void testPropertyComparatorEmptyPropertyNameAndPropertyValueConvertToClassAndNaturalComparator(){ new PropertyComparator<>("", Integer.class, ComparatorUtils.NATURAL_COMPARATOR); }
@Test(expected = IllegalArgumentException.class) public void testPropertyComparatorBlankPropertyNameAndPropertyValueConvertToClassAndNaturalComparator(){ new PropertyComparator<>(" ", Integer.class, ComparatorUtils.NATURAL_COMPARATOR); }
/** * Using an array of Comparators, applied in sequence until one returns not equal or the array is exhausted. */ public BeanQuery<T> orderBy(Comparator... beanComparator) { this.comparator = new DelegatedSortOrderableComparator(ComparatorUtils.chainedComparator(beanComparator)); return this; }
/** * 按照不同指定属性 <code>propertyNameAndOrders</code> 排序的 {@link Comparator}. * * @param <T> * the generic type * @param propertyNameAndOrders * 属性名称和排序因子, * * <p> * 格式可以是纯的属性名称, 比如 "name"; 也可以是属性名称+排序因子(以空格分隔),比如 "name desc" * </p> * * <h3>说明:</h3> * <blockquote> * * <dl> * <dt>关于属性名称</dt> * <dd> * 泛型T对象指定的属性名称,Possibly indexed and/or nested name of the property to be * modified,参见<a href="../../bean/BeanUtil.html#propertyName">propertyName</a>,<br> * 该属性对应的value 必须实现 {@link Comparable}接口. * </dd> * * <dt>关于排序因子</dt> * <dd> * 可以没有排序因子<br> * 如果有,值可以是asc(顺序),desc(倒序)两种;<br> * 如果没有,默认按照asc(顺序)排序;<br> * 此外,asc/desc忽略大小写 * </dd> * * </dl> * * </blockquote> * @return 如果propertyNameAndOrders是单值,那么直接调用 {@link #propertyComparator(String)} 返回 * @throws NullPointerException * 如果 <code>propertyNameAndOrders</code> 是null,<br> * 或者有元素是 null; * @throws IllegalArgumentException * 如果 <code>propertyNameAndOrders</code> 是empty,<br> * 或者有元素是 blank * @see org.apache.commons.collections4.ComparatorUtils#chainedComparator(java.util.Collection) * @since 1.10.2 support propertyNameAndOrder */ public static <T> Comparator<T> chainedComparator(String...propertyNameAndOrders){ Validate.notEmpty(propertyNameAndOrders, "propertyNameAndOrders can't be null/empty!"); //如果propertyNameAndOrders是单值,那么直接调用 com.feilong.core.util.comparator.BeanComparatorUtil.propertyComparator(String) 返回 if (1 == propertyNameAndOrders.length){ return propertyComparator(propertyNameAndOrders[0]); } //--------------------------------------------------------------- List<Comparator<T>> comparators = newArrayList(); for (String propertyNameAndOrder : propertyNameAndOrders){ Validate.notBlank(propertyNameAndOrder, "propertyNameAndOrder can't be blank!"); String[] propertyNameAndOrderArray = SortHelper.parsePropertyNameAndOrder(propertyNameAndOrder); //注意:此处不要使用 propertyComparator(propertyName) //因为,PropertyComparator 如果属性值相同,会使用其他规则继续比较(为了TreeMap/treeSet), //也就是说,通常而言一次就比较出顺序,后续的propertyNameAndOrders 就没作用了 Comparator instance = ComparatorUtils.nullHighComparator(ComparableComparator.comparableComparator()); //null排在最后面 BeanComparator<T> beanComparator = new BeanComparator<>(propertyNameAndOrderArray[0], instance); comparators.add(isAsc(propertyNameAndOrderArray) ? beanComparator : reversedComparator(beanComparator)); } return ComparatorUtils.chainedComparator(comparators); }
/** * Creates a comparator that inverts the comparison * of the given comparator. If you pass in <code>null</code>, * the ReverseComparator defaults to reversing the * natural order, as per {@link java.util.Collections#reverseOrder()}. * * @param comparator Comparator to reverse */ @SuppressWarnings("unchecked") public ReverseComparator(final Comparator<? super E> comparator) { this.comparator = comparator == null ? ComparatorUtils.NATURAL_COMPARATOR : comparator; }
/** * Constructs an instance with the given Transformer and a * {@link ComparableComparator ComparableComparator}. * * @param transformer what will transform the arguments to <code>compare</code> */ @SuppressWarnings("unchecked") public TransformingComparator(final Transformer<? super I, ? extends O> transformer) { this(transformer, ComparatorUtils.NATURAL_COMPARATOR); }
/** * Construct an instance that sorts <code>null</code> higher than any * non-<code>null</code> object it is compared with. When comparing two * non-<code>null</code> objects, the {@link ComparableComparator} is * used. **/ @SuppressWarnings("unchecked") public NullComparator() { this(ComparatorUtils.NATURAL_COMPARATOR, true); }
/** * Construct an instance that sorts <code>null</code> higher or lower than * any non-<code>null</code> object it is compared with. When comparing * two non-<code>null</code> objects, the {@link ComparableComparator} is * used. * * @param nullsAreHigh a <code>true</code> value indicates that * <code>null</code> should be compared as higher than a * non-<code>null</code> object. A <code>false</code> value indicates * that <code>null</code> should be compared as lower than a * non-<code>null</code> object. **/ @SuppressWarnings("unchecked") public NullComparator(final boolean nullsAreHigh) { this(ComparatorUtils.NATURAL_COMPARATOR, nullsAreHigh); }
/** * 如果 <code>comparators length ==1</code>,返回 comparators[0]; 否则返回 {@link ComparatorUtils#chainedComparator(Comparator...)}; * * @param <O> * the generic type * @param comparators * the comparators * @return the comparator * @since 1.8.2 */ @SafeVarargs private static <O> Comparator<O> toComparator(Comparator<O>...comparators){ return 1 == comparators.length ? comparators[0] : ComparatorUtils.chainedComparator(comparators); }