HashMap

  • 什么是HashSet?

    • 它实现了Set接口,HashSet是Set集合的子类
    • 有哈希表支持的,元素不可重复的哈希码值(实际上是一个HashMap的实例).
    • 它不保证set的迭代顺序(遍历元素的顺序),遍历元素的顺序和存储元素的顺序不一致.
    • 允许使用null元素.HashSet,范型的确定类型必须是引用数据类型,引用数据类型的默认初值就是null

    总结:无序,可为null,不可重复(由哈希码表支持),实质是一个hashMap

public static void main( String[] args )
    {
        //需求1:arrayList中有存放学生类,有学生张三\张三\李四,去重张三
        //创建另一个集合,通过对比实体,来去重
        List<Student> oldStu = new ArrayList<>();
        oldStu.add(new Student(1,"张三"));
        oldStu.add(new Student(1,"张三"));
        oldStu.add(new Student(2,"李四"));

        List<Student> newStu = new ArrayList<>();
        oldStu.forEach((stu) -> {
            if (!newStu.contains(stu)){
                newStu.add(stu);
            }
        });

        System.out.println(newStu);
        /**
         * 打印结果:[Student{id=1, name='张三'}, Student{id=1, name='张三'}, Student{id=2, name='李四'}]
         * 没有去重,原因:contains比较的是实体的equals方法 ----> if (o.equals(elementData[i])),同时对象类型是Object类型,
         * 所以比较的是对象的hashcode值.而每一次new 对象都会生成一个新的hash地址值,所以无法判断实体的内容是否相等.
         *
         * //contains
         * public boolean contains(Object o) {
         *      return indexOf(o) >= 0;
         * }
         *
         * //indexOf
         * public int indexOf(Object o) {
         *         if (o == null) {
         *             for (int i = 0; i < size; i++)
         *                 if (elementData[i]==null)
         *                     return i;
         *         } else {
         *             for (int i = 0; i < size; i++)
         *                 if (o.equals(elementData[i]))
         *                     return i;
         *         }
         *         return -1;
         *     }
         */


        //需求2:HashSet中有存放学生类,有学生张三\张三\李四,去重张三
        Set<Person> personSet = new HashSet<>();
        personSet.add(new Person(1,"张三"));
        personSet.add(new Person(1,"张三"));
        personSet.add(new Person(2,"李四"));

        System.out.println(personSet);
        /**
         * 1.打印结果:[Person{id=1, name='张三'}, Person{id=2, name='李四'}, Person{id=1, name='张三'}]
         * 没有去重,原因还是因为对象的hashCode()方法,因为在存放的时候,同样是存放的范型对象,每一个对象的创建都会
         * 在堆中申请新的内存空间,也就是默认调用了一次hashCode(),所以第一次add和第二次add,存放的本身就是不同的,所以没有去重.
         * 如何实现呢?
         * 同样的重写对象的hashCode()方法和equals()方法,以保证实体的去重
         * 2.打印结果:[Person{id=2, name='李四'}, Person{id=1, name='张三'}]
         *
         * public boolean add(E e) {
         *         return map.put(e, PRESENT)==null;
         *     }
         */


    }
class Person{

    private Integer id;
    private String name;

    public Person() {
    }

    public Person(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person)) return false;
        Person person = (Person) o;
        return Objects.equals(id, person.id) &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}
class Student{
    private Integer id;
    private String name;

    public Student() {
    }

    public Student(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

    //改进:重写equals方法,比较实体的内容
    //打印结果:[Student{id=1, name='张三'}, Student{id=2, name='李四'}]
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Student)) return false;
        Student student = (Student) o;
        return Objects.equals(id, student.id) &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}
posted @ 2018-11-23 14:20  lisongyu  阅读(156)  评论(0编辑  收藏  举报