集合Collection
一、Set
(1)例子1
package Set;
import java.util.HashSet;
/**
* @Auther: Xinbai
* @Date:2020/5/5 19:13
*/
public class SetTest1 {
public static void main(String[] args) {
HashSet set=new HashSet();
System.out.println(set.add("a"));
set.add("b");
set.add("c");
set.add("d");
System.out.println(set.add("a"));
System.out.println(set);
}
}
输出结果:
true
false
[a, b, c, d]
【说明】:Set有两种特性:无顺序,不包含重复的元素。
(2)例子2
package Set;
import java.util.HashSet;
/**
* @Auther: Xinbai
* @Date:2020/5/5 19:19
*/
public class SetTest2 {
public static void main(String[] args) {
HashSet set=new HashSet();
set.add(new People("zhangsan"));
set.add(new People("lisi"));
set.add(new People("zhangsan"));
System.out.println(set);
}
}
class People{
String name;
public People(String name){
this.name=name;
}
}
输出结果:
[Set.People@74a14482, Set.People@4554617c, Set.People@1540e19d]
【说明】:这边是两个不同的对象,他们的地址是不同的,所以hashCode值一定是不同的,所以一定可以放进这个Set里面
类的名字 + @ + hashCode的十六进制表示 从这边就可以知道:不同的对象hash code是不同的,他们返回出不同的地址,hash
code可以看做是他们地址的的表现形式,对于Object类来说。注意后面跟的那一串只是内部地址的表现形式,通过某一种机制转化来的。
(3)例子3
package Set;
import java.util.HashSet;
/**
* @Auther: Xinbai
* @Date:2020/5/5 19:19
*/
public class SetTest2 {
public static void main(String[] args) {
HashSet set = new HashSet();
set.add(people);
set.add(people);
System.out.println(set);
}
}
class People {
String name;
public People(String name) {
this.name = name;
}
}
输出结果:
[Set.People@4554617c]
package Set;
import java.util.HashSet;
/**
* @Auther: Xinbai
* @Date:2020/5/5 19:19
*/
public class SetTest2 {
public static void main(String[] args) {
HashSet set = new HashSet();
String s1=new String("a");
String s2=new String("a");
set.add(s1);
set.add(s2);
System.out.println(set);
}
}
输出结果:
[a]
【说明】:添加一个指定的元素增加到Set中,如果这个元素没有存在的话,更加正确的说法是,指定的元素e增加Set中如果这个元素e不包含满足(e= =null ? e2==null : e.equals(e2))[e2为空,则e也为空,如果e2不为空,则e.equals(e2)]这个条件的e2的话,如果这个元素已经存在,就不会修改这个Set并返回false,即不往Set中添加这个元素。
二、关于Object类的equals()方法的特点
1)、自反性:x.equals(x)应该返回true
2)、对称性:x.equals(y)为true,那么y.equal(x)也为true
3)、传递性:x.equals(y)为true并且y.equal(z)也为true,那么x.equals(z)为true
4)、一致性:x.equals(y)第一次调用为true,那么x.equals(y)的第二次,第三次,第n次调用也为true,前提条件是在比较之间没有改变x,也没用改变y。
5)、对于非空引用x,x.equals(null)返回false。
三、关于Object类的hashCode()方法的特点
1)、 在一个Java应用的执行过程中,当我们在相同的对象上调用hashCode()这个方法,必须返回相同的整数值,这个整数从第一次启动到另外一次启动这个相同的程序,它是不一定需要保持一致的。](这边可以理解为如果再一次Java应用去调用这个函数返回123,再调用的过程中,有可能接下来还会继续调用这个方法,则它的返回值也必须是123,但是如果退出了这个应用,下次再启动这个应用时,调用这个方法之后,有可能返回的是456了。
2)、 如果两个对象通过Object中的equals()方法比较是相等的话,那么在这两个对象上调用hashCode方法,它们返回的hashCode值也必须是一样的。
3)、如果两个对象根据Java中的Object类的equals()方法比较的话,它们是不相等的,那么再这两个对象上调用hashCode()方法必须生成不同的整型值,这种情况不一样要强制的,然而,程序员应该注意如果在不同的对象上产生了不同的的返回值,那么我们应该再hashtables上改进它的性能。
4)、根据实际的情况来来说,针对Objcet类的hashCode()方法来说,不同的对象会产生不同的整数值,(通常他们实现方式是在对象的内部地址转换成一个整数,但这种技术并非Java规范语言所强制的。
当使用 HashSet 时,hashCode()方法就会得到调用,判断已经存储在集合中的对象的 hash code 值是否与增加的对象的 hash code 值一致;如果不一致,直接加进去;如 果一致,再进行 equals 方法的比较,equals 方法如果返回 true,表示对象已经加进去了,就不会再增加新的对象,否则加进去。
四、实现
如果我们自己定义一个类,想让其内容一样,就不需要再往Set中添加了,比如两个学生的名字一样就不需要往Set中添加信息了,这在实际开发中很常见,因为实际开发更多的判断是否能往Set中放置是根据内容来决定的,而非地址来决定的。
实现方式:这种情况下必须重写hashCode()方法和equals()方法。
package Set;
import java.util.HashSet;
/**
* @Auther: Xinbai
* @Date:2020/5/6 20:48
*/
public class SetTest3 {
public static void main(String[] args) {
HashSet set=new HashSet();
Student s1=new Student("zhangsan");
Student s2=new Student("zhangsan");
set.add(s1);
set.add(s2);
System.out.println(set);
}
}
class Student{
String name;
public Student(String name){
this.name=name;
}
public int hashCode(){
return this.name.hashCode();
}
public boolean equals(Object obj){
if (this==obj){
return true;
}
if (null!=obj&&obj instanceof Student){
Student s=(Student)obj;
if (name.equals(s.name)){
return true;
}
}
return false;
}
}
输出结果:
[Set.Student@aa9c3074]
或者直接自动重写【idea】----右击—生成
package Set;
import java.util.HashSet;
import java.util.Objects;
/**
* @Auther: Xinbai
* @Date:2020/5/6 20:48
*/
public class SetTest3 {
public static void main(String[] args) {
HashSet set=new HashSet();
Student s1=new Student("zhangsan");
Student s2=new Student("zhangsan");
set.add(s1);
set.add(s2);
System.out.println(set);
}
}
class Student{
String name;
public Student(String name){
this.name=name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
输出结果:
[Set.Student@aa9c3093]