java--Set集合

一、Set子接口

  特点:无序、无下标、元素不可重复

  方法:全部继承自Collection中的方法。

package com.monv.jihe;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * 测试Set接口
 * 特点:1、无序、没有下标 2、不能重复
 * @author Administrator
 *
 */

public class Demo6 {
    public static void main(String[] args) {
        //创建集合
        Set <String> set = new HashSet<>();
        //1.添加元素
        set.add("小米");
        set.add("苹果");
        set.add("华为");
//        set.add("华为");//不能重复  所以这个添加不上
        System.out.println("数据个数:"+set.size());
        System.out.println(set.toString());
        
        //2.删除元素
//        set.remove("华为");
//        System.out.println("删除后个数:"+set.size());
//        System.out.println(set.toString());
        
        //3.遍历【重点】
        //3.1.增强for循环
        System.out.println("-----增强for循环------");
        for (String string : set) {
            System.out.println(string);
        }
        //3.2.使用迭代器循环
        System.out.println("-----使用迭代器------");
        Iterator<String> it= set.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
        //4.判断
        System.out.println("-----判断-------");
        System.out.println(set.contains("苹果"));
        System.out.println(set.isEmpty());
    }
}

二、Set的实现类

  1、HashSet(无序的)【重点】

    1). 基于HashCode计算元素存放位置。

    2).当存入元素的哈希码相同时,会调用equals进行确认,如果结构为True,则拒绝后者存入

package com.monv.jihe;

import java.util.HashSet;
import java.util.Iterator;

/**
 * HashSet集合的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * @author Administrator
 *
 */
public class Demo7 {
    public static void main(String[] args) {
        //新建集合
        HashSet<String> hashSet = new HashSet<>();
        
        //1.添加元素
        hashSet.add("苹果");
        hashSet.add("西瓜");
        hashSet.add("香蕉");
    
        System.out.println("元素个数:"+hashSet.size());
        System.out.println(hashSet.toString());

        //2.删除
//        hashSet.remove("苹果");
//        System.out.println("删除后元素个数:"+hashSet.size());
//        System.out.println(hashSet.toString());
        
        //3.遍历
        //3.1增强for循环
        System.out.println("------增强for循环------");
        for (String string : hashSet) {
            System.out.println(string);
        }
        //3.2迭代器循环
        System.out.println("-----迭代器循环------");
        Iterator<String> it = hashSet.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        //4.判断
        System.out.println("-------判断---------");
        System.out.println(hashSet.contains("西瓜"));
        System.out.println(hashSet.isEmpty());
                
    }
}

  2、HashSet的使用

    存储结构:哈希表(数组+链表+红黑树)

    存储过程(重复依据):

    (1)根据hashCode计算保存的位置,如果此位置为空,则直接保存,如果不为空则执行第二步

    (2)再执行equals方法,如果equals方法为True,则认为是重复的,否则,形成链表

    (3)重写HashCode() 和 equals()的快捷操作:Alt+Shift+S -->Generate HashCode() and equals()

package com.monv.jihe;

public class Student{
    private String name;
    private int age;
    
    public Student() {
        // TODO Auto-generated constructor stub
    }
        
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }

    @Override
    public int hashCode() {
        //为什么用31
        //(1)31是一个质数(素数),减少散列冲突(hashCode生成的位置尽量不一样)
        //(2)31提高执行效率 31*i=(i<<5)-i
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    //    @Override
//    public int hashCode() {
//        // TODO Auto-generated method stub
//        int iname = this.name.hashCode();
//        int age = this.age;
//        
//        return iname+age;
//    }
//    
//    @Override
//    public boolean equals(Object obj) {
//        //1.判断是否是同一个对象
//        if(this == obj) {
//            return true;
//        }
//        //2.判断是否为空
//        if(obj == null) {
//            return false;
//        }
//        //3.判断是否是Student类型
//        if (obj instanceof Student) {
//            Student s = (Student)obj;
//            //4.比较属性
//            if (this.name.equals(s.getName())&&this.age == s.getAge()) {
//                return true;
//            }
//        }
//        //5.不满足返回false
//        return false;
//    }
//    
}

---------------------------------------------------------------------
package com.monv.jihe;

import java.util.HashSet;
import java.util.Iterator;

/**
 * HashSet的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * 存储过程(重复依据)
 * (1)根据hashCode计算保存的位置,如果此位置为空,则直接保存,如果不为空则执行第二步
 * (2)再执行equals方法,如果equals方法为True,则认为是重复的,否则,形成链表
 * @author Administrator
 *
 */
public class Demo8 {
    public static void main(String[] args) {
        //定义集合
        HashSet<Student> students = new HashSet<>();
        //1.添加元素
        Student s1 = new Student("小明", 20);
        Student s2 = new Student("小花", 22);
        Student s3 = new Student("小亮", 21);
        
        students.add(s1);
        students.add(s2);
        students.add(s3);
//        students.add(s3);//重复
        //因为Student类中重写了hashCode方法和equals方法 所以在判断的时候 名字和年龄相同就认为是同一个对象 不会再添加了
        //没有重写hashCode方法和equals方法时,new Student("小亮", 21) 会创建一个新的对象 与s3 对象不相同 所以会添加进去
        students.add(new Student("小亮", 21));
        System.out.println("元素个数"+ students.size());
        System.out.println(students.toString());
        
        //2.删除元素
//        students.remove(s2);
//        System.out.println("删除后元素个数:"+students.size());
//        System.out.println(students.toString());
        //3.遍历
        //3.1 增强For循环
        System.out.println("-----增强for-----");
        for (Student student : students) {
            System.out.println(student.toString());
        }
        //3.2迭代器循环
        System.out.println("-----迭代器-----");
        Iterator<Student> it = students.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
        
        //4.判断
        System.out.println("-------判断---------");
        System.out.println(students.contains(s2));
        System.out.println(students.contains(new Student("小花", 22)));
        System.out.println(students.isEmpty());
        
        
    }
}

   3、TreeSet

    1).基于排列顺序实现元素不重复

    2).实现了SortedSet接口,对集合元素自动排序

    3).元素对象的类型必须实现Comparable接口,指定排序规则

    4).通过CompareTo方法确定是否为重复元素。

    TreeSet<String>实例

package com.monv.jihe;

import java.util.Iterator;
import java.util.TreeSet;

/**
 * TreeSet的使用
 * 存储结构:红黑树
 * @author Administrator
 * 
 */
public class Demo9 {
    public static void main(String[] args) {
        //创建集合
        TreeSet<String> treeSet = new TreeSet<>();
        
        //1.添加元素
        treeSet.add("xyz");
        treeSet.add("abc");
        treeSet.add("hello");
//        treeSet.add("xyz");重复
        
        System.out.println("元素个数:"+treeSet.size());
        System.out.println(treeSet.toString());
        
        //2.删除元素
//        treeSet.remove("xyz");
//        System.out.println("删除后元素个数:"+treeSet.size());
        
        //3.遍历
        //3.1增强For
        System.out.println("------增强for------");
        for (String string : treeSet) {
            System.out.println(string);
        }
        //3.2迭代器
        System.out.println("------迭代器-------");
        Iterator<String> it = treeSet.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
        
        //4.判断
        System.out.println("------判断------");
        System.out.println(treeSet.contains("abc"));
        System.out.println(treeSet.isEmpty());
    }
}

  TreeSet<object>实例

  元素必须要实现Comparable接口,compareTo()方法的返回值为0,认为是重复元素

package com.monv.jihe;

public class Student implements Comparable<Student>{
    private String name;
    private int age;
    
    public Student() {
        // TODO Auto-generated constructor stub
    }
        
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }

    @Override
    public int hashCode() {
        //为什么用31
        //(1)31是一个质数(素数),减少散列冲突(hashCode生成的位置尽量不一样)
        //(2)31提高执行效率 31*i=(i<<5)-i
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    
    @Override
    public int compareTo(Student o) {
        int n1 = this.name.compareTo(o.getName());
        int n2 = this.age - o.getAge();
        return n1==0?n2:n1;
    }
//    @Override
//    public int hashCode() {
//        // TODO Auto-generated method stub
//        int iname = this.name.hashCode();
//        int age = this.age;
//        
//        return iname+age;
//    }
//    
//    @Override
//    public boolean equals(Object obj) {
//        //1.判断是否是同一个对象
//        if(this == obj) {
//            return true;
//        }
//        //2.判断是否为空
//        if(obj == null) {
//            return false;
//        }
//        //3.判断是否是Student类型
//        if (obj instanceof Student) {
//            Student s = (Student)obj;
//            //4.比较属性
//            if (this.name.equals(s.getName())&&this.age == s.getAge()) {
//                return true;
//            }
//        }
//        //5.不满足返回false
//        return false;
//    }
//    
}
--------------------------------------
package com.monv.jihe;

import java.util.Iterator;
import java.util.TreeSet;

/**
 * 使用TreeSet保存数据
 * 存储结构:红黑树
 * 要求:元素必须要实现Comparable接口,compareTo()方法的返回值为0,认为是重复元素
 * @author Administrator
 *
 */
public class Demo10 {
    public static void main(String[] args) {
        //创建集合 
        TreeSet<Student> students = new TreeSet<>();
        //1.添加元素
        Student s1 = new Student("xyz", 20);
        Student s2 = new Student("hello", 21);
        Student s3 = new Student("abc", 22);
        
        //直接add会报错 com.monv.jihe.Student cannot be cast to java.lang.Comparable
        //因为其存储结构为红黑树,存储的时候需要比较元素,直接add不知道比较的是什么 所以元素必须要实现Comparable接口
        //在Student类中实现Comparable接口 然后重写compareTo的方法
        students.add(s1);
        students.add(s2);
        students.add(s3);
        
        System.out.println("元素个数:"+students.size());
        System.out.println(students.toString());
        
        //2.删除元素
//        students.remove(s1);
//        System.out.println("删除后元素个数:"+students.size());
//        System.out.println(students.toString());
        //3.遍历元素
        //3.1 增强For
        System.out.println("------ 增强For-----------");
        for (Student student : students) {
            System.out.println(student.toString());
        }
        //3.2迭代器
        System.out.println("------迭代器-----------");
        Iterator<Student> it= students.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }    }
}

  TreeSet 的 Comparator接口:实现定制比较(比较器)  在实例化的时候就已经定好了比较规则  

  Student类中就不用再实现 Comparable 接口了

package com.monv.jihe;

import java.util.Comparator;
import java.util.TreeSet;


/**
 * TreeSet集合的使用
 * Comparator:实现定制比较(比较器) 在实例化的时候就已经定好了比较规则
 * Comparable:可比较的
 * @author Administrator
 *
 */
public class Demo11 {
    public static void main(String[] args) {
        //创建集合 并指定了比较规则 先按年龄比 年龄相同 再按姓名比
        TreeSet<Student> students = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int n1 = o1.getAge() - o2.getAge();
                int n2 = o1.getName().compareTo(o2.getName());
                return n1==0?n2:n1;
            }
        });
        
        Student s1 = new Student("xyz", 20);
        Student s2 = new Student("wsx", 18);
        Student s3 = new Student("rfv", 21);
        Student s4 = new Student("edc", 21);
        
        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);
        
        System.out.println(students.toString());
                
    }
}

TreeSet 实例(使用TreeSet集合实现字符串按照长度进行排序)

package com.monv.jihe;

import java.util.Comparator;
import java.util.TreeSet;

/**
 * 要求:使用TreeSet集合实现字符串按照长度进行排序
 * helloworld zhangsan lisi wangwu xian beijing nanjing
 * 用Comparator接口实现定制比较
 * @author Administrator
 *
 */
public class Demo12 {
    public static void main(String[] args) {
        TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                int n1 = o1.length() - o2.length();
                int n2 = o1.compareTo(o2);
                return n1==0?n2:n1;
            }
        });
        
        treeSet.add("helloworld");
        treeSet.add("zhangsan");
        treeSet.add("lisi");
        treeSet.add("wangwu");
        treeSet.add("xian");
        treeSet.add("beijing");
        treeSet.add("nanjing");
        System.out.println(treeSet.toString());
    }
}

 

posted @ 2020-11-01 16:56  改Bug的小魔女  阅读(289)  评论(0编辑  收藏  举报