主要内容
java中的==、equals()和hashCode()
算法题leetcode[15]:3Sum
java中的==、equals()和hashCode() “==”运算符 首先来看最基础的==符号,它比较的是变量(栈)内存中存放的对象(堆)的内存地址,用来判断两个对象的地址是否相同,即是否指向同一个对象。简单来说==比较的是,是否指向同一个对象(堆)
1 2 3 4 5 6 7 8 9 10 11 12 public static void main (String[] args) { String str1 = new String ("abc" ); String str2 = new String ("abc" ); String str3 = "efg" ; String str4 = "efg" ; System.out.println(str1==str2); System.out.println(str3==str4); }
现象解释:str1==str2输出false,是因为str1和str2虽然存储的字符串相同,但是它们各自new了自己单独的对象,而==比较的是指向的对象是否相同,所以输出false。 而str3==str4是因为java中变量池 的存在,定义str3和str4的时候,java回到变量池中寻找是否存在已经定义过的,如果有已经定义了的,那么直接将引用指向它就可以了,不必再重新新建对象了。因为str3和str4指向同一个对象,所以str3==str4为true。
equals() 首先看一段代码我们写了一个Myobj,并new了两个对象,分别使用==和equals()来进行比较
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class Test { public static void main (String[] args) { Myobj obj1 = new Myobj ("aaa" ); Myobj obj2 = new Myobj ("aaa" ); System.out.println(obj1==obj2); System.out.println(obj1.equals(obj2)); } } class Myobj { String name; public Myobj (String name) { this .name=name; } }
现象解释: obj1==obj2输出false,很好理解,因为==比较的是指向的对象是否是同一个,因为obj1和obj2指向了它们各自new的对象,所以为false。obj1.equals(obj2)输出false,是因为我们在Myobj没有重写equals()方法,使用的是Object中的equals()方法.Object类中的equals()方法的实现
1 2 3 public boolean equals (Object obj) { return (this == obj); }
看到了Object类中的equals()方法的实现,对obj1.equals(obj2)输出false也很好理解了,因为它本质上和obj1==obj2是一样的。重写equals()方法: 如果我们认为name相同的MyObject对象就是equals的的话,我们就需要重写equals()方法了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class Test { public static void main (String[] args) { Myobj obj1 = new Myobj ("aaa" ); Myobj obj2 = new Myobj ("aaa" ); System.out.println(obj1==obj2); System.out.println(obj1.equals(obj2)); } } class Myobj { public String name; public Myobj (String name) { this .name=name; } public boolean equals (Myobj obj) { return this .name.equals(obj.name); } }
hashCode()
hashCode()方法的作用是什么 HashCode()方法主要是在哈希表中起作用,如HashSet、HashMap等。单我们向哈希表中添加对象的时候,首先会调用hashCode()方法计算Object的哈希码,根据哈希码的值,确定该对象在哈希表中的位置,如果该位置已经有对象了,那么就调用equals()比较这些对象与Object是否相等,如果相等,则不需要保存object对象,如果不相等,则把对象加入链表中。 这也就解释了equals()相等,则hashCode()必须相等 ,如果两个对象equals相等,那么它们在哈希表中应该只出现一次,如果hashCode不相等,那么它们会被散列到哈希表中的不同位置,就不止出现一次了。
重写hashCode() 几个原则:
equals相等,则hashCode必须相等(重点)
hashCode不能太简单,否则哈希冲突会很多
hashCode不能太复杂,否则计算耗时,影响性能
Object类中的hashCode方法:
1 public native int hashCode () ;
重写hashcode
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public class Test { public static void main (String[] args) { Myobj obj1 = new Myobj ("aaa" ,1 ); Myobj obj2 = new Myobj ("aaa" ,1 ); System.out.println(obj1.equals(obj2)); System.out.println(obj1.hashCode()==obj2.hashCode()); } } class Myobj { public String name; public int id; public Myobj (String name,int id) { this .name=name; this .id=id; } public boolean equals (Myobj obj) { return this .name.equals(obj.name)&&this .id==obj.id; } @Override public int hashCode () { int hash = 17 ; hash=hash*31 +name.hashCode(); hash=hash*31 +id; return hash; } }
《Effective Java》中提出的一种重写hashCode的方法:
初始化一个整形变量,并赋予一个非零的常数
选取equals方法中用于比较的所有域,然后针对每个域的属性进行计算(确保原则一)
将每个域的散列码合并到对象的哈希码中
算法题leetcode[15]:3Sum 题目: Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note: The solution set must not contain duplicate triplets.
Example: Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
分析: 首先对数据进行排序,然后固定也给位置,从两边进行夹逼。
解法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 class Solution { List <List<Integer>> result = new ArrayList <List<Integer>>(); public List <List<Integer>> threeSum (int [] nums) { if (nums==null ||nums.length<3 ){ return result; } Arrays.sort(nums); for (int i = 0 ;i<nums.length-2 ;i++){ if (i>0 &&nums[i]==nums[i-1 ]){ continue ; } find(nums,i+1 ,nums.length-1 ,nums[i]); } return result; } private void find (int [] nums,int begin,int end,int target) { int l = begin; int r = end; while (l<r){ if ((nums[l]+nums[r]+target)==0 ){ List <Integer> list = new ArrayList <Integer>(); list.add(target); list.add(nums[l]); list.add(nums[r]); result.add(list); while (l<r&&nums[l]==nums[l+1 ]){ l++; } while (l<r&&nums[r]==nums[r-1 ]){ r--; } l++; r--; }else if ((nums[l]+nums[r]+target)<0 ){ l++; }else { r--; } } } }