Think It
public static void main(String[] args) {
List<String> stringList = Arrays.asList("1", "2");
List<Long> longList = Arrays.asList(1L, 2L);
longList.removeAll(stringList);
System.out.println(longList.toString());
}
Summary
不仅是个错误使用问题,反应自己对这块的只是库存不足
removeAll 方法流程
最终是内存地址相同的时候,才判断有效(这里在删除对象的时候,必须内存地址一样才能删除,除非重写equals方法)
public boolean equals(Object obj) {
return (this == obj);
}
但如果构造的内容是List<String>,因为String 重写了equals方法,所以会比较内容,内容相同即可(但是必须是String类型,我们在上面例子中,删除的是Long,所以无效)
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
重写equals方法要符合规范
/**
* Indicates whether some other object is "equal to" this one.
* <p>
* The {@code equals} method implements an equivalence relation
* on non-null object references:
* <ul>
* <li>It is <i>reflexive</i>: for any non-null reference value
* {@code x}, {@code x.equals(x)} should return
* {@code true}.
* <li>It is <i>symmetric</i>: for any non-null reference values
* {@code x} and {@code y}, {@code x.equals(y)}
* should return {@code true} if and only if
* {@code y.equals(x)} returns {@code true}.
* <li>It is <i>transitive</i>: for any non-null reference values
* {@code x}, {@code y}, and {@code z}, if
* {@code x.equals(y)} returns {@code true} and
* {@code y.equals(z)} returns {@code true}, then
* {@code x.equals(z)} should return {@code true}.
* <li>It is <i>consistent</i>: for any non-null reference values
* {@code x} and {@code y}, multiple invocations of
* {@code x.equals(y)} consistently return {@code true}
* or consistently return {@code false}, provided no
* information used in {@code equals} comparisons on the
* objects is modified.
* <li>For any non-null reference value {@code x},
* {@code x.equals(null)} should return {@code false}.
* </ul>
* <p>
* The {@code equals} method for class {@code Object} implements
* the most discriminating possible equivalence relation on objects;
* that is, for any non-null reference values {@code x} and
* {@code y}, this method returns {@code true} if and only
* if {@code x} and {@code y} refer to the same object
* ({@code x == y} has the value {@code true}).
* <p>
* Note that it is generally necessary to override the {@code hashCode}
* method whenever this method is overridden, so as to maintain the
* general contract for the {@code hashCode} method, which states
* that equal objects must have equal hash codes.
*
* @param obj the reference object with which to compare.
* @return {@code true} if this object is the same as the obj
* argument; {@code false} otherwise.
* @see #hashCode()
* @see java.util.HashMap
*/
public boolean equals(Object obj) {
return (this == obj);
}
翻译成中文:
equals 方法实现的时候必须要满足的特性:
1.(reflexive)自反性:
对于任何非 null 的引用值 x,x.equals(x) 必须为 true;
2.(symmetric)对称性:
对于任何非 null 的引用值 x,y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 也要返回 true 。
3.(transitive)传递性:
对于任何非 null 的引用值 x,y,z, 如果 x.equals(y) 返回 true,y.equals(z) 返回 true,那么 x.equals(z) 一定要返回 true。
4.(consistent)一致性:
对于任何非 null 的引用值 x,y,只要 equals() 方法没有修改的前提下,多次调用 x.equals(y) 的返回结果一定是相同的。
5.(non-nullity)非空性
对于任何非 null 的引用值 x,x.equals(null) 必须返回 false。
覆盖 equals 时,一定要同时覆盖 hashCode !!!
这样做的目的是保证每一个 equals()返回 true 的两个对像,要有两个相同的 hashCode 。 重写方法的快捷键 command+N
in the end
一个在面试的时候,经常被问到的 java 基础题:
java 中 == 和 equals 和 hashCode 的区别?
java 中有两种类型,值类型和引用类型。其中,== 值类型和引用类型都可以运算,equals 和 hashCode 是引用类型特有的方法。
对于值类型,== 比较的是它们的值,对于引用类型,== 比较的是两者在内存中的物理地址。
equals() 是 Object 类中的方法,默认实现是使用 == 比较两个对象的地址,但是在一些子类,例如 String,Float,Integer 等,它们对 equals进行覆盖重写,就不再是比较两个对象的地址了。
hashCode() 也是 Object 类的一个方法。返回一个离散的 int 型整数。在集合类操作中使用,为了提高查询速度。
当覆盖 equals() 的时候,一定要同时覆盖 hashCode(),保证 x.equals(y) 返回为 true 的时候,x,y 要有相同的 HashCode 。