Java/Class/Equals
Содержание
Compares two objects for equality, where either one or both objects may be null
<source lang="java">
/*
* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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. */
import java.io.Serializable; /**
*Operations on Object
.
**
This class tries to handle null
input gracefully.
* An exception will generally not be thrown for a null
input.
* Each method documents its behaviour in more detail.
* * @author * @since 1.0 * @version $Id: ObjectUtils.java 594336 2007-11-12 22:54:02Z bayard $ */
public class ObjectUtils {
/***
Singleton used as a null
placeholder where
* null
has another meaning.
**
For example, in a HashMap
the
* {@link java.util.HashMap#get(java.lang.Object)} method returns
* null
if the Map
contains
* null
or if there is no matching key. The
* Null
placeholder can be used to distinguish between
* these two cases.
**
Another example is Hashtable
, where null
* cannot be stored.
**
This instance is Serializable.
*/ public static final Null NULL = new Null(); /***
ObjectUtils
instances should NOT be constructed in
* standard programming. Instead, the class should be used as
* ObjectUtils.defaultIfNull("a","b");
.
**
This constructor is public to permit tools that require a JavaBean instance * to operate.
*/ public ObjectUtils() { super(); } // Defaulting //----------------------------------------------------------------------- /***
Returns a default value if the object passed is
* null
.
**
* ObjectUtils.defaultIfNull(null, null) = null * ObjectUtils.defaultIfNull(null, "") = "" * ObjectUtils.defaultIfNull(null, "zz") = "zz" * ObjectUtils.defaultIfNull("abc", *) = "abc" * ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE *
* * @param object the*Object
to test, may benull
* @param defaultValue the default value to return, may benull
* @returnobject
if it is notnull
, defaultValue otherwise */ public static Object defaultIfNull(Object object, Object defaultValue) { return object != null ? object : defaultValue; } /**
Compares two objects for equality, where either one or both
* objects may be null
.
**
* ObjectUtils.equals(null, null) = true * ObjectUtils.equals(null, "") = false * ObjectUtils.equals("", null) = false * ObjectUtils.equals("", "") = true * ObjectUtils.equals(Boolean.TRUE, null) = false * ObjectUtils.equals(Boolean.TRUE, "true") = false * ObjectUtils.equals(Boolean.TRUE, Boolean.TRUE) = true * ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false *
* * @param object1 the first object, may be*null
* @param object2 the second object, may benull
* @returntrue
if the values of both objects are the same */ public static boolean equals(Object object1, Object object2) { if (object1 == object2) { return true; } if ((object1 == null) || (object2 == null)) { return false; } return object1.equals(object2); } /**
Gets the hash code of an object returning zero when the
* object is null
.
**
* ObjectUtils.hashCode(null) = 0 * ObjectUtils.hashCode(obj) = obj.hashCode() *
*
* @param obj the object to obtain the hash code of, may be null
* @return the hash code of the object, or zero if null
* @since 2.1
*/
public static int hashCode(Object obj) {
return (obj == null) ? 0 : obj.hashCode();
}
// Identity ToString
//-----------------------------------------------------------------------
/**
* Gets the toString that would be produced by Object
* if a class did not override toString itself. null
* will return null
.
**
* ObjectUtils.identityToString(null) = null * ObjectUtils.identityToString("") = "java.lang.String@1e23" * ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa" *
* * @param object the object to create a toString for, may be **null
* @return the default toString text, ornull
if *null
passed in */ public static String identityToString(Object object) { if (object == null) { return null; } StringBuffer buffer = new StringBuffer(); identityToString(buffer, object); return buffer.toString(); } /**
Appends the toString that would be produced by Object
* if a class did not override toString itself. null
* will throw a NullPointerException for either of the two parameters.
**
* ObjectUtils.identityToString(buf, "") = buf.append("java.lang.String@1e23" * ObjectUtils.identityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa" * ObjectUtils.identityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa") *
* * @param buffer the buffer to append to * @param object the object to create a toString for * @since 2.4 */ public static void identityToString(StringBuffer buffer, Object object) { if (object == null) { throw new NullPointerException("Cannot get the toString of a null identity"); } buffer.append(object.getClass().getName()) .append("@") .append(Integer.toHexString(System.identityHashCode(object))); }
// ToString //----------------------------------------------------------------------- /***
Gets the toString
of an Object
returning
* an empty string ("") if null
input.
**
* ObjectUtils.toString(null) = "" * ObjectUtils.toString("") = "" * ObjectUtils.toString("bat") = "bat" * ObjectUtils.toString(Boolean.TRUE) = "true" *
* * @see StringUtils#defaultString(String) * @see String#valueOf(Object) * @param obj the Object to*toString
, may be null * @return the passed in Object"s toString, or nullStr ifnull
input * @since 2.0 */ public static String toString(Object obj) { return obj == null ? "" : obj.toString(); } /**
Gets the toString
of an Object
returning
* a specified text if null
input.
**
* ObjectUtils.toString(null, null) = null * ObjectUtils.toString(null, "null") = "null" * ObjectUtils.toString("", "null") = "" * ObjectUtils.toString("bat", "null") = "bat" * ObjectUtils.toString(Boolean.TRUE, "null") = "true" *
* * @see StringUtils#defaultString(String,String) * @see String#valueOf(Object) * @param obj the Object totoString
, may be null * @param nullStr the String to return ifnull
input, may be null * @return the passed in Object"s toString, or nullStr ifnull
input * @since 2.0 */ public static String toString(Object obj, String nullStr) { return obj == null ? nullStr : obj.toString(); }
// Null //----------------------------------------------------------------------- /***
Class used as a null placeholder where null
* has another meaning.
**
For example, in a HashMap
the
* {@link java.util.HashMap#get(java.lang.Object)} method returns
* null
if the Map
contains
* null
or if there is no matching key. The
* Null
placeholder can be used to distinguish between
* these two cases.
**
Another example is Hashtable
, where null
* cannot be stored.
*/ public static class Null implements Serializable { /** * Required for serialization support. Declare serialization compatibility with Commons Lang 1.0 * * @see java.io.Serializable */ private static final long serialVersionUID = 7092611880189329093L; /** * Restricted constructor - singleton. */ Null() { super(); } /***
Ensure singleton.
* * @return the singleton value */ private Object readResolve() { return ObjectUtils.NULL; } }
}
</source>
Equals(Equal) Method
<source lang="java">
//: c03:EqualsMethod2.java // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt.
class Value {
int i;
} public class EqualsMethod2 {
public static void main(String[] args) { Value v1 = new Value(); Value v2 = new Value(); v1.i = v2.i = 100; System.out.println(v1.equals(v2)); }
} ///:~
</source>
Equals Method
<source lang="java">
//: c03:EqualsMethod.java // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt.
public class EqualsMethod {
public static void main(String[] args) { Integer n1 = new Integer(47); Integer n2 = new Integer(47); System.out.println(n1.equals(n2)); }
} ///:~
</source>
Equivalence
<source lang="java">
//: c03:Equivalence.java // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt.
public class Equivalence {
static Test monitor = new Test(); public static void main(String[] args) { Integer n1 = new Integer(47); Integer n2 = new Integer(47); System.out.println(n1 == n2); System.out.println(n1 != n2); }
} ///:~
</source>
Equivalence ClassSet
<source lang="java">
/**
* EquivalenceClassSet.java * * @author bret5 * Copyright(C) 2007 bret5 * * This is a specialized set class which groups the elements into * equivalence classes based on the by the comparator provided at * set creation time. Iterators created thru the standard set interface * will return elements sorted by comparator order. Elements that * are equivalent may be returned in any order. * * The class also provides a special loopIterator iteration * which will return each element once in comparator order, then loop back * around to the first element at the end. The loopIterator continues to be valid * as add/remove operations are performed. If shuffleEquivalenceClasses is set, * it will randomly shuffles the elements in each equivalence class * every time that equivalence class is reached during iteration. If not, * each equivalence class will be returned in the same order every time. * shuffleEquivalenceClasses defaults to true. * * This Set does not allow null elements. * * This was written for a program that uses jdk 1.4, so it doesn"t yet use the generic style. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
import java.util.AbstractSet; import java.util.ArrayList; import java.util.ruparator; import java.util.ConcurrentModificationException; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.NoSuchElementException; /**
* @author bret5 * */
public class EquivalenceClassSet<T> extends AbstractSet<T> {
// the list backing the class. This is a list of the // equivalence classes - each equivalence class is a sublist // which contains all the elements equivalent to each other. // The sublists appear in order corresponding to the ordering // provided by the comparator provided at set creation time. private List m_equivalenceClasses; private int m_size; // cached for efficiency private Comparator m_comparator; private ListIterator m_loopEqvClassIter; // non-null index used by the loop iterator private List m_loopCurrentEqvClass; // ptr to current class, null ok private ListIterator<T> m_loopItemIter; // non-null index used by the loop iterator private final static List m_emptyList = new ArrayList(); // emptyList used for gen-ing iterators // In order to maintain some sanity in the face of objects changing with respect to // the comparator after being added to the set, we keep track of which class every object // is in. This way, the behavior of contains and remove are undisturbed by changes to the // objects. private HashMap m_itemToClassMap; // TODO - size is now redundant with the size of the item-class map, remove... private int m_changeID; // supports iterator fail-fast, increment on each modification private boolean m_shuffleEquivalenceClasses; /* * Class invariants: * Individual equivalence classes may not be empty * The cached size is equal to the sum of all items in the sublists * The changeID increments montonically whenever the set contents are changed, * although it does reset on a clear() */ public EquivalenceClassSet(Comparator<T> c) { super(); m_comparator = c; m_equivalenceClasses = new LinkedList(); m_size = 0; m_itemToClassMap = new HashMap(); resetLoopIterator(); m_changeID = 0; m_shuffleEquivalenceClasses = true; } protected class OnePassIterator implements Iterator<T> { private int localChangeID; private ListIterator localEqvClassIter; // class iter private ListIterator<T> localItemIter; // item iter protected OnePassIterator() { localChangeID = m_changeID; localEqvClassIter = m_equivalenceClasses.listIterator(); // index used by the loop iterator localItemIter = null; // null means before the next class } public boolean hasNext() { if (m_changeID != localChangeID) { throw new ConcurrentModificationException(); } if (localEqvClassIter.hasNext() || (localItemIter != null && localItemIter.hasNext())) { return true; } return false; } public T next() { if (m_changeID != localChangeID) { throw new ConcurrentModificationException(); } if (localItemIter == null || !localItemIter.hasNext()) { localItemIter = ((List)localEqvClassIter.next()).listIterator(); } return localItemIter.next(); } public void remove() { throw new UnsupportedOperationException(); } } public Iterator<T> iterator() { return new OnePassIterator(); } // Note that this iterator is intended to continue iteration after element addition // and removal. Therefore we put the underlying iterators in the main class so that // they can be adjusted/replaced when necessary // invariants: // if size = 0, currentEqvClassIter is null. // if size not null, then both currentEqvClassIter and currentItemIter // are not null. protected class LoopIterator implements Iterator<T> { public boolean hasNext() { return ( m_size > 0 ); } public T next() { assert m_loopEqvClassIter != null; assert m_loopItemIter != null; if (m_size <= 0) { throw new NoSuchElementException(); } // first, move to a new class if necessary, resetting the item iter. // if switching classes, shuffle. if (!m_loopItemIter.hasNext()) { if (!m_loopEqvClassIter.hasNext()) { // recycle to beginning m_loopEqvClassIter = m_equivalenceClasses.listIterator(); } m_loopCurrentEqvClass = (List)m_loopEqvClassIter.next(); assert m_loopCurrentEqvClass.size() > 0; if (m_shuffleEquivalenceClasses) { java.util.Collections.shuffle(m_loopCurrentEqvClass); } m_loopItemIter = m_loopCurrentEqvClass.listIterator(); } return m_loopItemIter.next(); } public void remove() { throw new UnsupportedOperationException(); } } /** * The loopIterator is a special iteration for which hasNext() returns * true if the size is greater than 0. The next() method * traverses the equivalence classes in comparator order. Within * each equivalence class, the items are returned randomly * (by shuffling the elements in the equivalence class every time * that equivalence class is reached during iteration). * * Iteration can be reset to the first equivalence class by using * the resetLoopIterator method of the main class. * * @return the iterator */ public Iterator<T> loopIterator() { return new LoopIterator(); } public void resetLoopIterator() { m_loopEqvClassIter = m_equivalenceClasses.listIterator(); m_loopCurrentEqvClass = null; m_loopItemIter = m_emptyList.listIterator(); } /** * If shuffleEquivalenceClasses is set, the loopItertor will randomly shuffle * the elements in each equivalence class every time that equivalence class * is reached during iteration. * * @return the value of shuffleEquivalenceClasses */ public boolean isShuffleEquivalenceClasses() { return m_shuffleEquivalenceClasses; } /** * Set the value of shuffleEquivalenceClasses. * @see isShuffleEquivalenceClasses() */ public void setShuffleEquivalenceClasses(boolean shuffleEquivalenceClasses) { this.m_shuffleEquivalenceClasses = shuffleEquivalenceClasses; } /* (non-Javadoc) * @see java.util.AbstractCollection#size() */ public int size() { return m_size; } /* * Adds the argument to the collection. If the element is not already * a member of the set, and is equivalent to the current equivalence * class, it is added so that it will be returned before any element * from another class is returned. */ public boolean add(T arg0) { return addPositional(arg0, true); } /* * Adds the argument to the collection. If the element is not already * a member of the set, and is equivalent to the current equivalence * class, it is added so that it will not be returned before an element * from another class is returned (if there are any other classes). */ public boolean addExpired(T arg0) { return addPositional(arg0, false); } protected boolean addPositional(Object arg0, boolean atEnd) { EqvPosition eqvPosition = findEqvClass(arg0); boolean isChanged = false; if (eqvPosition.matchingEqvClass != null) { int iterIdx = 0; boolean replaceLoopItemIter = false; if (eqvPosition.matchingEqvClass == m_loopCurrentEqvClass) { // we have to replace the item loop iterator for this class, so get the position replaceLoopItemIter = true; iterIdx = m_loopItemIter.nextIndex(); } if (!eqvPosition.matchingEqvClass.contains(arg0)) { if (atEnd) { eqvPosition.matchingEqvClass.add(arg0); } else { eqvPosition.matchingEqvClass.add(0, arg0); iterIdx += 1; } isChanged = true; if (replaceLoopItemIter) { m_loopItemIter = m_loopCurrentEqvClass.listIterator(iterIdx); } } } else { // there is no matching class, so add one ArrayList newEqvClass = new ArrayList(); newEqvClass.add(arg0); eqvPosition.matchingEqvClass = newEqvClass; // cache the eqv class ref for adding to map int iterIdx, addIdx; iterIdx = 0; addIdx = 0; if (m_size >= 1) { iterIdx = m_loopEqvClassIter.nextIndex(); addIdx = eqvPosition.eqvClassIter.nextIndex(); if (addIdx < iterIdx) { iterIdx += 1; } } eqvPosition.eqvClassIter.add(newEqvClass); isChanged = true; // replace the class loop iterator m_loopEqvClassIter = m_equivalenceClasses.listIterator(iterIdx); // if the new class is next and the add is "expired"/(not atEnd), // advance the iterator past the just added item if (iterIdx == addIdx && !atEnd && !m_loopItemIter.hasNext()) { m_loopCurrentEqvClass = (List)m_loopEqvClassIter.next(); m_loopItemIter = m_loopCurrentEqvClass.listIterator(1); } } if (isChanged) { m_size += 1; m_changeID += 1; m_itemToClassMap.put(arg0, eqvPosition.matchingEqvClass); } return isChanged; } // represents the location of the equivalence class matching a value. // returned from findEqvClass, so we only have to write that code once. // If there is a matching class, then matchingEqvClass will be non-null. // If not, then eqvClassIter holds the position that eqv class would have. protected class EqvPosition { protected List matchingEqvClass; protected ListIterator eqvClassIter; } // If there is a matching class, then matchingEqvClass will be non-null. // If not, then eqvClassIter holds the position that eqv class would have. protected EqvPosition findEqvClass(Object arg0) { EqvPosition eqvPosition = new EqvPosition(); if (m_itemToClassMap.containsKey(arg0)) { eqvPosition.matchingEqvClass = (List)m_itemToClassMap.get(arg0); return eqvPosition; // note that the iterator will be null. } eqvPosition.eqvClassIter = m_equivalenceClasses.listIterator(); while (eqvPosition.eqvClassIter.hasNext()) { List testEqvClass = (List)eqvPosition.eqvClassIter.next(); assert testEqvClass.size() > 0; int comparison = m_comparator.rupare(arg0, testEqvClass.get(0)); if (comparison < 0) { // there is no matching class, to insert before this one, return the previous position if (eqvPosition.eqvClassIter.hasPrevious()) { eqvPosition.eqvClassIter.previous(); } break; } else if (comparison == 0) { eqvPosition.matchingEqvClass = testEqvClass; return eqvPosition; } // and fall through to the next eqvClass } return eqvPosition; } /* (non-Javadoc) * @see java.util.AbstractCollection#clear() */ public void clear() { m_equivalenceClasses.clear(); m_itemToClassMap.clear(); m_size = 0; m_changeID = 0; // can reset to original state resetLoopIterator(); } /* (non-Javadoc) * @see java.util.AbstractCollection#contains(java.lang.Object) */ public boolean contains(Object arg0) { EqvPosition eqvPosition = findEqvClass(arg0); if (eqvPosition.matchingEqvClass != null && eqvPosition.matchingEqvClass.contains(arg0)) { return true; // already a member, do nothing } return false; } /* (non-Javadoc) * @see java.util.AbstractCollection#remove(java.lang.Object) */ public boolean remove(Object arg0) { assert m_size == m_itemToClassMap.size(); EqvPosition eqvPosition = findEqvClass(arg0); return removeAtPosition(eqvPosition, arg0); } /* (non-Javadoc) * @see java.util.AbstractCollection#remove(java.lang.Object) */ private boolean removeAtPosition(EqvPosition eqvPosition, Object arg0) { // when removing an object, we may have to replace the item loop iterator // if we removed an item from the current loop class // also, if the removal results in removal of a class, we may have to // replace the class loop iter boolean isChanged = false; boolean replaceLoopItemIter = false; if (eqvPosition.matchingEqvClass != null) { int itemLocationIdx = 0; int loopNextItemIdx = 0; int itemClassIdx = 0; int loopNextClassIdx = 0; itemLocationIdx = eqvPosition.matchingEqvClass.indexOf(arg0); if (itemLocationIdx >= 0) { // the item is a member of this class and will be removed isChanged = true; if (eqvPosition.matchingEqvClass == m_loopCurrentEqvClass) { // we may have to replace the item loop iterator for this class, so get the position replaceLoopItemIter = true; loopNextItemIdx = m_loopItemIter.nextIndex(); if (itemLocationIdx < loopNextItemIdx) { loopNextItemIdx -= 1; } } eqvPosition.matchingEqvClass.remove(arg0); if (eqvPosition.matchingEqvClass.size() <= 0) { // the class is now empty, remove it loopNextClassIdx = m_loopEqvClassIter.nextIndex(); itemClassIdx = m_equivalenceClasses.indexOf(eqvPosition.matchingEqvClass); if (itemClassIdx < loopNextClassIdx) { loopNextClassIdx -= 1; } m_equivalenceClasses.remove(eqvPosition.matchingEqvClass); // and replace the loop iterator, and maybe the item iterator if (m_equivalenceClasses.size() == 0) { resetLoopIterator(); } else { m_loopEqvClassIter = m_equivalenceClasses.listIterator(loopNextClassIdx); if (eqvPosition.matchingEqvClass == m_loopCurrentEqvClass) { m_loopCurrentEqvClass = null; m_loopItemIter = m_emptyList.listIterator(); } } } else if (replaceLoopItemIter) { // replace the item iterator for the class m_loopItemIter = m_loopCurrentEqvClass.listIterator(loopNextItemIdx); } } } if (isChanged) { m_itemToClassMap.remove(arg0); m_size -= 1; assert m_size >= 0; assert m_size == m_itemToClassMap.size(); m_changeID += 1; } return isChanged; } public Comparator<T> getComparator() { return m_comparator; } /** * Partition this set into two sets, returning the new one. * * The argument specifies how many elements to put in the new set. Elements will be * chosen in comparator order. All elements put into the new set will be removed from * this set. If the original set contained less elements than the argument, then * after the partition the new set will contain all the elements and the original set * will be empty. * * If the partition is non-trivial (that is, if the new set contains at least one * element), then the counters for the loop iterator will be reset. * * @param numberToRemove number of elements to remove from the original set * * @return the new set */ public EquivalenceClassSet<T> partition(int numberToRemove) { EquivalenceClassSet<T> newSet = new EquivalenceClassSet<T>(m_comparator); while (numberToRemove > 0 && m_size > 0) { ArrayList firstEqvClass = (ArrayList)(m_equivalenceClasses.get(0)); int sizeOfFEqvClass = firstEqvClass.size(); int numberMoved = 0; List movedEqvClass; if (numberToRemove >= sizeOfFEqvClass) { movedEqvClass = (List)m_equivalenceClasses.remove(0); newSet.m_equivalenceClasses.add(movedEqvClass); numberMoved = sizeOfFEqvClass; } else { // shuffle the equivalence class prior to a partial selection if (m_shuffleEquivalenceClasses) { java.util.Collections.shuffle(firstEqvClass); } movedEqvClass = new ArrayList(firstEqvClass.subList(0, numberToRemove)); firstEqvClass.subList(0, numberToRemove).clear(); newSet.m_equivalenceClasses.add(movedEqvClass); numberMoved = numberToRemove; } m_size -= numberMoved; newSet.m_size += numberMoved; numberToRemove -= numberMoved; // now fix up the item to class map Iterator iter = movedEqvClass.iterator(); while (iter.hasNext()) { Object obj = iter.next(); m_itemToClassMap.remove(obj); newSet.m_itemToClassMap.put(obj, movedEqvClass); } } if (newSet.size() > 0) { newSet.resetLoopIterator(); resetLoopIterator(); m_changeID += 1; newSet.m_changeID += 1; } assert m_size == m_itemToClassMap.size(); assert newSet.m_size == newSet.m_itemToClassMap.size(); return newSet; } /** * In some cases, the equivalence class of an object will change. This can leave * the list in an inconsistent state. It is essential to fix the problem. * This method moves the object to the correct equivalence class, keeping the * loopIterator where it was. * * @param arg0 The object to move. * @return true if the object is a member of the set, false otherwise. */ public boolean resetEquivalenceClass(T arg0) { boolean found = false; EqvPosition eqvPosition = new EqvPosition(); eqvPosition.matchingEqvClass = (List)m_itemToClassMap.get(arg0); if (eqvPosition.matchingEqvClass != null) { removeAtPosition(eqvPosition, arg0); found = true; } if (found) { addExpired(arg0); } return found; }
}
</source>
If the given objects are equal
<source lang="java">
import java.lang.reflect.Array; import java.util.Arrays; /*
* Copyright 2002-2007 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. */
//Revised from springframework /**
* Miscellaneous object utility methods. Mainly for internal use within the * framework; consider Jakarta"s Commons Lang for a more comprehensive suite * of object utilities. * * @author Juergen Hoeller * @author Keith Donald * @author Rod Johnson * @author Rob Harrop * @author Alex Ruiz * @since 19.03.2004 * @see org.apache.rumons.lang.ObjectUtils */
abstract class ObjectUtils {
private static final int INITIAL_HASH = 7; private static final int MULTIPLIER = 31; private static final String EMPTY_STRING = ""; private static final String NULL_STRING = "null"; private static final String ARRAY_START = "{"; private static final String ARRAY_END = "}"; private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END; private static final String ARRAY_ELEMENT_SEPARATOR = ", ";
/** * Determine if the given objects are equal, returning*true
* if both arenull
orfalse
if only one is *null
.
Compares arrays with Arrays.equals
, performing an equality
* check based on the array elements rather than the array reference.
* @param o1 first Object to compare
* @param o2 second Object to compare
* @return whether the given objects are equal
* @see java.util.Arrays#equals
*/
public static boolean nullSafeEquals(Object o1, Object o2) {
if (o1 == o2) {
return true;
}
if (o1 == null || o2 == null) {
return false;
}
if (o1.equals(o2)) {
return true;
}
if (o1 instanceof Object[] && o2 instanceof Object[]) {
return Arrays.equals((Object[]) o1, (Object[]) o2);
}
if (o1 instanceof boolean[] && o2 instanceof boolean[]) {
return Arrays.equals((boolean[]) o1, (boolean[]) o2);
}
if (o1 instanceof byte[] && o2 instanceof byte[]) {
return Arrays.equals((byte[]) o1, (byte[]) o2);
}
if (o1 instanceof char[] && o2 instanceof char[]) {
return Arrays.equals((char[]) o1, (char[]) o2);
}
if (o1 instanceof double[] && o2 instanceof double[]) {
return Arrays.equals((double[]) o1, (double[]) o2);
}
if (o1 instanceof float[] && o2 instanceof float[]) {
return Arrays.equals((float[]) o1, (float[]) o2);
}
if (o1 instanceof int[] && o2 instanceof int[]) {
return Arrays.equals((int[]) o1, (int[]) o2);
}
if (o1 instanceof long[] && o2 instanceof long[]) {
return Arrays.equals((long[]) o1, (long[]) o2);
}
if (o1 instanceof short[] && o2 instanceof short[]) {
return Arrays.equals((short[]) o1, (short[]) o2);
}
return false;
}
}
</source>
Test the equality of two object arrays
<source lang="java">
import java.lang.reflect.Array; /*
* JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */
public class Main {
/** * Test the equality of two object arrays. * * @param a The first array. * @param b The second array. * @param deep True to traverse elements which are arrays. * @return True if arrays are equal. */ public static boolean equals(final Object[] a, final Object[] b, final boolean deep) { if (a == b) return true; if (a == null || b == null) return false; if (a.length != b.length) return false; for (int i=0; i<a.length; i++) { Object x = a[i]; Object y = b[i]; if (x != y) return false; if (x == null || y == null) return false; if (deep) { if (x instanceof Object[] && y instanceof Object[]) { if (! equals((Object[])x, (Object[])y, true)) return false; } else { return false; } } if (! x.equals(y)) return false; } return true; } /** * Test the equality of two object arrays. * * @param a The first array. * @param b The second array. * @return True if arrays are equal. */ public static boolean equals(final Object[] a, final Object[] b) { return equals(a, b, true); }
}
</source>