解决方案 »
- 关于int转integer问题!
- 求个漂亮的css样式表
- 进行JAVA学习采用何种操作系统
- 怎样计算命令行参数数字的字节数?
- 急!!socket网络编程问题,在线!
- java虚拟机是否就是jre。
- 请问各位大侠:如何在页面中设置,使当不能显示APPLET时候,自动让用户去我们自己的tomcat服务器(局域网内)而不要从sun站点上下载JAVA
- jsp编译错误。。。。请高人指教(在线等待)
- 我的jdk1.3里面怎么看不到什么java.lang等包呢
- 怎样读取表名
- JNative动行时提示Unloading native library 'BargaingApply'
- read(byte[] b) java inputstream问题
如果你输出之前这样做:
t=t1;
输出的就是true了。
另外,比如我自己的类里写的新的方法,equals(当前类 类名),这其实是重载了,然后调用equals,他应该会调用自己写的方法,而不会调用Object里面的equals方法吧?其实两个方法都符合,为什么优先调用自己的equals呢
另外,比如我自己的类里写的新的方法,equals(当前类 类名),这其实是重载了,然后调用equals,他应该会调用自己写的方法,而不会调用Object里面的equals方法吧?其实两个方法都符合,为什么优先调用自己的equals呢
对于第一个,的确是调用了自己写的equals方法,然后判断两者是否相等,这里所谓的相等是基于你写的equals方法而言的,可能两个年龄相同的学生对象就是相等的,但这两个对象不是同一个对象,分别有不同的内存地址,所以“这样的比较能说明两个是同一个对象”是不正确的。
对于第二个,是设计好的内部规则,虚拟机会根据方法名先找与自己实际引用类型相同的那个类下面的同名方法(参数类型也是符合的),如果没找到,然后再找超类中符合条件的。
具体参考核心卷 5.1.3动态绑定章节,部分内容如下
重新equals 方法 和 hashcode方法,只是为了通过在比较两个对象的内容上是否相等,从而判断这两个对象是否相等,这个只是业务上的相等,不是java里面的== 的相等。
另外,HashSet底层是采用这样的机制来判断的:
1st & ( 2nd || 3rd )
hashCode( ) & ( == || equals( ) )对应jdk源码中是这样的:e.hash == hash && ((k = e.key) == key || key.equals(k))
再加个小例子:public class TestHashSetJdk{
public static void main(String[] args){
Set<Student> set = new HashSet<Student>();
Student s1 = new Student("小明");
Student s2 = new Student("小强");
set.add(s1);
set.add(s1); //再次添加同一个对象
set.add(s2); //比较组
for(Student s : set)
System.out.println(s.name);
}
}class Student{
String name;
public Student(String name){
this.name = name;
} @Override
public int hashCode(){
return 1;
} @Override
public boolean equals(Object obj){
return false;
}
}
另外,比如我自己的类里写的新的方法,equals(当前类 类名),这其实是重载了,然后调用equals,他应该会调用自己写的方法,而不会调用Object里面的equals方法吧?其实两个方法都符合,为什么优先调用自己的equals呢java中所有类默认继承自Object类,而你的类重写了equals()方法,当你new一个你的类的对象时,能.出什么(调用什么方法、属性),看你的类型;而具体执行哪个方法,是看对象,你创建的你所建的类对象,就执行你的类里面的equals()方法了。总之这是向上造型、重写什么的,你可以去看看书哈!呵呵!
另外,比如我自己的类里写的新的方法,equals(当前类 类名),这其实是重载了,然后调用equals,他应该会调用自己写的方法,而不会调用Object里面的equals方法吧?其实两个方法都符合,为什么优先调用自己的equals呢
对于第一个,的确是调用了自己写的equals方法,然后判断两者是否相等,这里所谓的相等是基于你写的equals方法而言的,可能两个年龄相同的学生对象就是相等的,但这两个对象不是同一个对象,分别有不同的内存地址,所以“这样的比较能说明两个是同一个对象”是不正确的。
对于第二个,是设计好的内部规则,虚拟机会根据方法名先找与自己实际引用类型相同的那个类下面的同名方法(参数类型也是符合的),如果没找到,然后再找超类中符合条件的。
具体参考核心卷 5.1.3动态绑定章节,部分内容如下
好的,谢谢
/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element <tt>e</tt> to this set if
* this set contains no element <tt>e2</tt> such that
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns <tt>false</tt>.
*
* @param e element to be added to this set
* @return <tt>true</tt> if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}而map的put底层是这样实现的:
/**
* Implements Map.put and related methods
*
* @param hash hash for key
* @param key the key
* @param value the value to put
* @param onlyIfAbsent if true, don't change existing value
* @param evict if false, the table is in creation mode.
* @return previous value, or null if none
*/
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
可以覆盖equalse方法.