java第十七讲集合中的接口

一、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]

猜你喜欢

转载自blog.csdn.net/qq_44830627/article/details/105937385