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 方法流程

list的removeall方法根据什么移除 list.removeall(list)_引用类型

最终是内存地址相同的时候,才判断有效(这里在删除对象的时候,必须内存地址一样才能删除,除非重写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 。