Set集合讲解


1.Set集合

1.1 Set集合的概述和特点

  • 不可以存储重复的元素
  • 存取顺序不一致
  • 没有索引,不能使用普通for循环遍历

1.2 Set集合的使用

  • 使用set集合存储字符串
public static void main(String[] args) {
        Set<String> set = new TreeSet<>();
        set.add("四大发明");
        set.add("造纸术");
        set.add("印刷术");
        set.add("火药");
        set.add("指南针");
        set.add("指南针");
//        for (int i = 0; i < set.size(); i++) {
//            // Set集合是没有索引的,所以不能使用通过索引获取元素的方法
//        }
        Iterator it = (Iterator) set.iterator();
        while (it.hasNext()) {
            Object s = it.next();
            System.out.print(s + " ");//印刷术 四大发明 指南针 火药 造纸术
        }
        System.out.println();
        for (String s : set) {
            System.out.print(s + " ");//印刷术 四大发明 指南针 火药 造纸术 
        }
    }

2. TreeSet集合

2.1 TreeSet集合概述和特点

  • 不可以存储重复的元素
  • 没有索引
  • 可以将元素按照规则进行排序(存储自定义元素时,要制定排序规则)
    TreeSet(): 根据元素的自然排序进行排序
    TreeSet(Comparator comparator): 根据指定的比较器进行排序

2.2 TreeSet集合的基本使用

存储Integer类型的整数并遍历

public static void main(String[] args) {
    TreeSet<Integer> ts = new TreeSet<>();
    ts.add(1);
    ts.add(5);
    ts.add(6);
    ts.add(2);
    ts.add(3);
    ts.add(9);
    System.out.println(ts);//[1, 2, 3, 5, 6, 9]
}

2.3 自然排序Comparable的使用

  • 案例需求
    存储Person对象并遍历, 创建TreeSet集合使用无参构造方法
    要求:按照年龄从小到大排序,年龄相同是,按照姓名的字母进行排序

  • 实现步骤
    a. 使用空参构造创建TreeSet集合
    用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的。
    b.自定义的Person类实现Comparable接口
    自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法。
    c.重写接口中的compareTo方法
    重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写。

  • 代码实现

@Override
public int compareTo(Person o) {
    //按照对象的年龄进行排序, 主要判断条件
    int result = (int)(this.age - o.age);
    // this表示正在存储的元素, o表示已经存进去的对象, 次要判断条件,使用的是字符串的compareTo(按照字典顺序进行排序)
    result = result == 0 ? this.name.compareTo(o.getName()) : result;
    return result;
}

测试类

public static void main(String[] args) {
    TreeSet<Person> ts = new TreeSet<>();
    Person s1 = new Person("libai", 61);
    Person s2 = new Person("liubei", 47);
    Person s3 = new Person("machao", 32);
    Person s5 = new Person("me", 21);
    Person s4 = new Person("caopi", 21);

    ts.add(s1);
    ts.add(s2);
    ts.add(s3);
    ts.add(s4);
    ts.add(s5);
    // 直接存储就会报错
    System.out.println(ts);//[Person{name='caopi', age=21.0}, Person{name='me', age=21.0}, Person{name='machao', age=32.0}, Person{name='liubei', age=47.0}, Person{name='libai', age=61.0}]
}

2.4 比较器排序

  • 案例需求
    存储Person对象并遍历,创建TreeSet集合使用带参数的构造方法
    要求: 按年龄从小到大排序,年龄相同时,按照姓名的字母顺序进行排序

  • 实现步骤
    用TreeSet结合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
    比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法
    重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写。

  • 代码示例

public static void main(String[] args) {
    TreeSet<Person> ts = new TreeSet<>(new Comparator<Person>() {
        @Override
        public int compare(Person o1, Person o2) {
            // 其中o1表示现在要存入的元素,o2表示已经存入到集合中的元素
            // 主要条件
            int result = (int)(o1.getAge() - o2.getAge());
            // 次要条件
            result = result == 0 ? o1.getName().compareTo(o2.getName()) : result;
            return result;
        }
    });
    Person s1 = new Person("libai", 61);
    Person s2 = new Person("liubei", 47);
    Person s3 = new Person("machao", 32);
    Person s5 = new Person("me", 21);
    Person s4 = new Person("caopi", 21);

    ts.add(s1);
    ts.add(s2);
    ts.add(s3);
    ts.add(s4);
    ts.add(s5);
    // 直接存储就会报错
    System.out.println(ts);//[Person{name='caopi', age=21.0}, Person{name='me', age=21.0}, Person{name='machao', age=32.0}, Person{name='liubei', age=47.0}, Person{name='libai', age=61.0}]
}

2.5 小结

  • 两种比较方式
    自然排序: 自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序
    比较器排序: 创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序
    在使用的时候,默认使用自然排序,当自然排序不满足现在的需求时(比如对字符串进行排序),必须使用比较器排序
  • 两种方式中关于返回值的规则
    如果返回值为负数,表示当前存入的元素是较小值,存左边
    如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存
    如果返回值为正数,表示当前存入的元素是较大值,存右边

【案例】对字符串进行排序

// 可以用lambda一行搞定,虽然这样不美观.....
public static void main(String[] args) {
    TreeSet<String> ts = new TreeSet<>(
            (String o1, String o2) -> (o1.length() - o2.length()) == 0 ? o1.compareTo(o2) : (o1.length() - o2.length()));
    ts.add("c");
    ts.add("df");
    ts.add("ab");
    ts.add("quer");
    ts.add("s2");
    // 直接存储就会报错
    System.out.println(ts);//[Person{name='caopi', age=21.0}, Person{name='me', age=21.0}, Person{name='machao', age=32.0}, Person{name='liubei', age=47.0}, Person{name='libai', age=61.0}]
}

如果本篇内容对你有帮助的话,就点一个赞吧,您的支持是我继续创作的动力!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值