001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.functor.core.comparator; 018 019 import java.io.Serializable; 020 import java.util.Comparator; 021 022 import org.apache.commons.functor.BinaryPredicate; 023 import org.apache.commons.functor.UnaryPredicate; 024 import org.apache.commons.functor.adapter.RightBoundPredicate; 025 026 /** 027 * A {@link BinaryPredicate BinaryPredicate} that {@link #test tests} 028 * <code>true</code> iff the left argument is equal to the 029 * right argument under the specified {@link Comparator}. 030 * When no (or a <code>null</code> <code>Comparator</code> is specified, 031 * a {@link Comparable Comparable} <code>Comparator</code> is used. 032 * 033 * @see org.apache.commons.functor.core.IsEqual 034 * 035 * @version $Revision: 1166340 $ $Date: 2011-09-07 21:44:28 +0200 (Wed, 07 Sep 2011) $ 036 * @author Rodney Waldhoff 037 * 038 */ 039 public final class IsEquivalent<T> implements BinaryPredicate<T, T>, Serializable { 040 041 /** 042 * Basic IsEquivalent instance. 043 */ 044 public static final IsEquivalent<Comparable<?>> INSTANCE = IsEquivalent.<Comparable<?>> instance(); 045 046 /** 047 * serialVersionUID declaration. 048 */ 049 private static final long serialVersionUID = -6392784113015793664L; 050 051 private final Comparator<? super T> comparator; 052 053 /** 054 * Create a new IsEquivalent. 055 */ 056 @SuppressWarnings("unchecked") 057 public IsEquivalent() { 058 this(ComparableComparator.INSTANCE); 059 } 060 061 /** 062 * Construct an <code>IsEquivalent</code> {@link BinaryPredicate predicate} 063 * for the given {@link Comparator Comparator}. 064 * 065 * @param comparator the {@link Comparator Comparator}, when <code>null</code>, 066 * a <code>Comparator</code> for {@link Comparable Comparable}s will 067 * be used. 068 */ 069 public IsEquivalent(Comparator<? super T> comparator) { 070 if (comparator == null) { 071 throw new IllegalArgumentException("Comparator must not be null"); 072 } 073 this.comparator = comparator; 074 } 075 076 /** 077 * Return <code>true</code> iff the <i>left</i> parameter is 078 * equal to the <i>right</i> parameter under my current 079 * {@link Comparator Comparator}. 080 * {@inheritDoc} 081 */ 082 public boolean test(T left, T right) { 083 return comparator.compare(left, right) == 0; 084 } 085 086 /** 087 * {@inheritDoc} 088 */ 089 public boolean equals(Object that) { 090 return that == this || (that instanceof IsEquivalent<?> && equals((IsEquivalent<?>) that)); 091 } 092 093 /** 094 * Learn whether a given IsEquivalent is equal to this. 095 * @param that IsEquivalent to test 096 * @return boolean 097 */ 098 public boolean equals(IsEquivalent<?> that) { 099 if (null != that) { 100 if (null == comparator) { 101 return null == that.comparator; 102 } 103 return comparator.equals(that.comparator); 104 } 105 return false; 106 } 107 108 /** 109 * {@inheritDoc} 110 */ 111 public int hashCode() { 112 int hash = "IsEquivalent".hashCode(); 113 // by construction, comparator is never null 114 hash ^= comparator.hashCode(); 115 return hash; 116 } 117 118 /** 119 * {@inheritDoc} 120 */ 121 public String toString() { 122 return "IsEquivalent<" + comparator + ">"; 123 } 124 125 /** 126 * Get a basic IsEquivalent instance. 127 * @param T 128 * @return IsEquivalent<T> 129 */ 130 @SuppressWarnings("unchecked") 131 public static <T extends Comparable<?>> IsEquivalent<T> instance() { 132 return new IsEquivalent<T>(ComparableComparator.INSTANCE); 133 } 134 135 /** 136 * Get an IsEquivalent instance that always compares to <code>arg</code>. 137 * @param right argument 138 * @return UnaryPredicate 139 */ 140 public static <T extends Comparable<?>> UnaryPredicate<T> instance(T right) { 141 return RightBoundPredicate.bind(instance(), right); 142 } 143 144 }