Java集合:Set集合的使用

先看集合框架图:

Java集合:Set集合的使用_第1张图片

Set有HashSet和TreeSet两种实现类。

先看Set:

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

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

增、删、遍历、判断与collection一致

看代码:

package com.collections.set;

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

/**
 * set的使用
 * 特点:(1)无序(2)不能重复
 * @author 华子
 */
public class Demo01 {
    public static void main(String[] args) {
        Set set = new HashSet<>();
//        添加
        set.add("小米");
        set.add("苹果");
        set.add("华为");
        set.add("华为");
        System.out.println(set.size());
        System.out.println(set.toString());
//        删除
//        set.remove("苹果");
//        System.out.println("删除后:"+set.size());
//        System.out.println(set.toString());
//        遍历
//       增强for
        for (String s :set
             ) {
            System.out.println(s);
        }
        System.out.println("------------------------");
//        迭代器
        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            String s = iterator.next();
            System.out.println(s);
        }
        System.out.println("------------------------");
        for (String s :set) {
            System.out.println(s);
        }
//        判断
        System.out.println(set.contains("华为"));
        System.out.println(set.isEmpty());
    }
}

和之间的集合使用方法类似。

HasSet【重点】

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

存储过程(重复依据)

  1. 根据hashCode计算保存的位置,如果位置为空,直接保存,若不为空,进行第二步
  2. 再执行equals方法,如果equals为true,则认为是重复,否则形成链表

特点

存储过程:

  • 基于HashCode计算元素存放位置
    • 利用31这个质数,减少散列冲突
      • 31提高执行效率 31 * i = (i << 5) - i 转为移位操作
    • 当存入元素的哈希码相同时,会调用equals进行确认,如果结果为true,则拒绝后者存入

新建集合 HashSet hashSet = new HashSet();

添加元素 hashSet.add( );

删除元素 hashSet.remove( );

遍历操作

​ 1. 增强for for( type type : hashSet)

​ 2. 迭代器 Iterator it = hashSet.iterator( );

判断 hashSet.contains( ); hashSet.isEmpty();

先看HashSet的使用:

    package com.collections.set;

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

    /**
     * HashSet的使用
     * 存储结构:哈希表(数组+链表+红黑树)
     * @author 华子
     */
    public class Demo02 {
        public static void main(String[] args) {
            HashSet hashSet = new HashSet<>();
    //        1.添加元素
            hashSet.add("刘德华");
            hashSet.add("郭富城");
            hashSet.add("张学友");
            hashSet.add("黎明");
            System.out.println("元素个数为:"+hashSet.size());
            System.out.println(hashSet.toString());
    //        删除元素
    //        hashSet.remove("刘德华");
    //        System.out.println("删除后:"+hashSet.size());
    //        System.out.println(hashSet.toString());

    //        遍历元素
    //       增强for
            for (String s :hashSet
            ) {
                System.out.println(s);
            }
            System.out.println("------------------------");
    //        迭代器
            Iterator iterator = hashSet.iterator();
            while (iterator.hasNext()){
                String s = iterator.next();
                System.out.println(s);
            }

        }
    }

 还是差不多。

再来看HashSet存储Person类:

package com.collections.set;

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

/**
 * HashSet的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * 存储过程:
 * (1)根据hashCode值计算保存的位置,如果为空,直接保存,如果不为空,则进入第二步
 * (2)执行equals,如果为true,则判断为重复,否则,形成链表
 * @author 华子
 */
public class Demo03 {
    public static void main(String[] args) {
        HashSet hashSet = new HashSet<>();
        Person p1 = new Person("刘德华",20);
        Person p2 = new Person("郭富城",21);
        Person p3 = new Person("张学友",22);
        Person p4 = new Person("黎明",23);
        hashSet.add(p1);
        hashSet.add(p2);
        hashSet.add(p3);
        hashSet.add(p4);
        hashSet.add(new Person("刘德华",20));
        System.out.println("元素个数为:"+hashSet.size());
        System.out.println(hashSet.toString());
//        删除
//        hashSet.remove(new Person("刘德华",20));
//        System.out.println("元素个数为:"+hashSet.size());
//        System.out.println(hashSet.toString());

//        遍历元素
//       增强for
        for (Person p :hashSet
        ) {
            System.out.println(p);
        }
        System.out.println("------------------------");
//        迭代器
        Iterator iterator = hashSet.iterator();
        while (iterator.hasNext()){
            Person p = iterator.next();
            System.out.println(p);
        }
    }
}

Person类:

package com.collections.set;

import java.util.Objects;

/**
 * 人类
 * @author 华子
 * 实现Comparable接口
 */
public class Person implements Comparable{
    private String name;
    private  int age;

    public Person() {
    }

    public Person(String name, int age) {
        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 "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

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

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
//  重写了比较方法,先按姓名比,再按年龄比
    @Override
    public int compareTo(Person o) {
        int n1 = this.getName().compareTo(o.getName());
        int n2 = this.getAge() - o.getAge();
        return n1==0?n2:n1;
    }
}

由于存储方式是先看HashCode计算位置,那个位置不为空,才进行equal,

我们再Person类中重写hasCode和equal方法:

Java集合:Set集合的使用_第2张图片

使得它的haCode的是通过name和age生成,且equal比较的是属性。

这样就可以实现相同属性无法添加了、可以通过属性相同进行删除

Java集合:Set集合的使用_第3张图片 

运行结果:

Java集合:Set集合的使用_第4张图片 

可见HashSet的存储方式。

TreeSet:

特点

  • 基于排列顺序实现元素不重复
  • 实现SortedSet接口,对集合元素自动排序
  • 元素对象的类型必须实现Comparable接口,指定排序规则
  • 通过CompareTo方法确定是否为重复元素

存储结构:红黑树

创建集合 TreeSet treeSet = new TreeSet<>()

添加元素 treeSet.add();

删除元素 treeSet.remove();

遍历 1. 增强for 2. 迭代器

判断 treeSet.contains();

补充:TreeSet集合的使用

Comparator 实现定制比较(比较器)

Comparable 可比较的

TreeSet的使用:

package com.collections.set;

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

/**
 * TreeSet的使用
 * @author 华子
 *
 */
public class Demo04 {
    public static void main(String[] args) {
//        创建集合
        TreeSet treeSet = new TreeSet<>();
        treeSet.add("xxx");
        treeSet.add("yyy");
        treeSet.add("zzz");
        treeSet.add("xxx");
        System.out.println("元素个数:"+treeSet.size());
        System.out.println(treeSet.toString());
//        删除
//        treeSet.remove("xxx");
//        System.out.println("删除之后:"+treeSet.size());
//        遍历
//        增强for循环
        for (String s:treeSet) {
            System.out.println(s);
        }
        System.out.println("----------------------------");
//        使用迭代器
        Iterator iterator = treeSet.iterator();
        while (iterator.hasNext()){
            String s = iterator.next();
            System.out.println(s);
        }
    }
}

和其他集合方法使用类似。 

TreeSet存储Person类:

因为TreeSet存储的元素对象的类型必须实现Comparable接口,指定排序规则,而Peron中的对象没有固定的属性方法,所以Person要实现Comparable接口并重写compareTo方法。

Person类:

package com.collections.set;

import java.util.Objects;

/**
 * 人类
 * @author 华子
 * 实现Comparable接口
 */
public class Person implements Comparable{
    private String name;
    private  int age;

    public Person() {
    }

    public Person(String name, int age) {
        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 "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

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

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
//  重写了比较方法,先按姓名比,再按年龄比
    @Override
    public int compareTo(Person o) {
        int n1 = this.getName().compareTo(o.getName());
        int n2 = this.getAge() - o.getAge();
        return n1==0?n2:n1;
    }
}

Java集合:Set集合的使用_第5张图片 

 

Java集合:Set集合的使用_第6张图片 

这样就可以进行元素存储了(排序方式先比姓名,再比年龄):

package com.collections.set;

import java.util.TreeSet;

/**
 * TreeSet存储Peron类
 * 存储结构:红黑树
 * 要求:元素必须实现Comparable接口,compareTo返回值为0,则确认为重复
 * @author 华子
 */
public class Demo05 {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet<>();
        Person p1 = new Person("aaa",18);
        Person p2 = new Person("bbb",19);
        Person p3 = new Person("ccc",20);
        Person p4 = new Person("ddd",21);
        Person p5 = new Person("ddd",22);
        treeSet.add(p1);
        treeSet.add(p2);
        treeSet.add(p3);
        treeSet.add(p4);
        treeSet.add(p5);
        System.out.println("元素个数:"+treeSet.size());
        System.out.println(treeSet.toString());

    }
}

运行结果:

Java集合:Set集合的使用_第7张图片 

还可以用Comparator 定制比较器(使用匿名内部类):

直接再匿名内部类里重写比较方法:

package com.collections.set;

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

/**
 * @author 华子
 * TreeSet的使用
 * Comparator 定制比较(比较器) 使用匿名内部类
 * Comparable,可比较的
 */
public class Demo06 {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet(new Comparator() {
            @Override
            public int compare(Person p1, Person p2) {
                int n1 = p1.getAge() - p2.getAge();
                int n2 = p1.getName().compareTo(p2.getName());
                return n1==0?n2:n1;
            }
        });
        Person p1 = new Person("aaa",18);
        Person p2 = new Person("bbb",19);
        Person p3 = new Person("ccc",20);
        Person p4 = new Person("ddd",21);
        Person p5 = new Person("eee",21);
        treeSet.add(p1);
        treeSet.add(p2);
        treeSet.add(p3);
        treeSet.add(p4);
        treeSet.add(p5);
        System.out.println(treeSet.toString());

    }
}

运行结果:

这样也可以添加元素。 

TreeSet案例:

使用TreeSet实现字符串按长度排序:hello world zhangsan lisi wangwu xian najing 

package com.collections.set;

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

/**
 * TreeSet案例:使用TreeSet实现字符串按长度排序
 * hello world zhangsan lisi wangwu xian najing
 * @author 华子
 *
 */
public class Demo07 {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet<>(new Comparator() {
            @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("hello world");
        treeSet.add("zhangsan");
        treeSet.add("lisi");
        treeSet.add("wangwu");
        treeSet.add("xian");
        treeSet.add("najing");
        System.out.println(treeSet.toString());
    }
}

运行结果:

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Java学习进阶,java,开发语言)