美文网首页
Topic17:Set集合

Topic17:Set集合

作者: KaveeDJ | 来源:发表于2019-01-23 15:21 被阅读0次

17.01 HashSet存储字符串并遍历

  • Set并没有什么特殊的方法,我们主要学习它方法的实现(即如何保证元素不重复)
  • HashSet类实现了Set接口
  • Set集合是无索引,不可以重复,无序存取不一致
  • 只要能用迭代器迭代的,就可以使用增强for循环遍历

17.02 HashSet存储自定义对象,保证元素唯一性

  • 底层是用hashCode实现(hashCode是Object的方法)

17.03 HashSet保证对象的唯一性的原理

  • 先调用hashCode方法,如果返回值一样,就去调用equals方法
  • 让程序自动生成hashCode和equals方法
  • hashCode返回的结果尽量不同,这样可以降低equals方法的调用,提高效率
  • 我们做开发的时候,自动重写equals方法和hashCode方法就可以了

17.04 HashSet如何保证元素唯一性的原理

  • hashCode里面为什么定义31这个常量

    • 31是一个质数,公约数少,重复的概率低
    • 31不大不小
    • 31这个数好算,是2的5次方减1,2左移5位减1
  • 将自定义类的对象存入HashSet去重复

    • 类中必须重写hashCode()和equals()方法
    • hashCode():属性相同的对象返回值必须相同,属性不同的返回值尽量不同(提高效率)
    • equals();属性相同返回true,属性不同返回false,返回false的时候存储

17.05 LinkedHashSet的概述和使用

  • 底层是链表实现的,是set集合中唯一一个能保证怎么存就怎么取的集合对象
  • 因为是HashSet的子类,所以也是保证元素唯一的,与HashSet的原理一样

17.06 产生10个1-20的随机数(要求随机数不能重复)

package com.kevin.test;

import java.util.HashSet;
import java.util.Random;

public class Test1 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Random r = new Random();
        HashSet<Integer> hs = new HashSet<>();
        while(hs.size() < 10) {
            hs.add(r.nextInt(20) +1 );
        }
        for (Integer integer : hs) {
            System.out.println(integer);
        }
    }

}

17.07 练习一

  • 使用Scanner从键盘读取一行输入,去掉其中重复字符,打印出不同的那些字符(顺序打印)
  • aaaaddddgggghjjjj
package com.kevin.test;

import java.util.LinkedHashSet;
import java.util.Scanner;

public class Test2 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一行字符串:");
        LinkedHashSet<Character> lhs = new LinkedHashSet<>();
        String line = sc.nextLine();
        char[] arr = line.toCharArray();
        
        for (char c : arr) {
            lhs.add(c);
        }
        
        for (Character ch : lhs) {
            System.out.println(ch);
        }
    }

}

17.08 练习二

  • 将集合中的重复元素去掉
package com.kevin.test;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;

public class Test3 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("a");
        list.add("a");
        list.add("b");
        list.add("b");
        list.add("b");
        list.add("b");
        list.add("b");
        list.add("c");
        list.add("c");
        list.add("c");
        list.add("c");
        
        getSingle(list);
        
        System.out.println(list);
    }

    public static void getSingle(List<String> list) {
        LinkedHashSet<String> lhs = new LinkedHashSet<>();
        lhs.addAll(list);
        list.clear();
        list.addAll(lhs);
    }

}

17.09 TreeSet存储Integer类型的元素并遍历

  • TreeSet集合是用来对元素进行排序的,同样它也可以保证元素的唯一

17.10 TreeSet存储自定义对象

  • 实现某一个接口,就是增加特定的方法。
  • 实现comparable接口,重写compareTo方法
  • compare方法的返回值
    • 返回0的时候:集合中只有一个元素
    • 返回正数的时候:集合会正序存储
    • 返回负数的时候:集合会倒序存储

17.11 TreeSet保证元素唯一和自然排序的原理和图解

  • TreeSet底层是二叉树
  • 小的存储在左边,大的存储在右边,相等就不存
  • 重写比较的方法

17.12 TreeSet存储自定义对象并遍历练习

  • 按照中文姓名去排序,底层是Unicode编码

17.13 按照姓名长度排序

  • 使用length方法

17.14 TreeSet保证元素唯一和比较器排序的原理

  • String类里面重写了compareTo方法,按字典顺序比较两个字符串,不考虑大小写
  • comparator接口:比较器

17.15 TreeSet原理

  • 特点
    • TreeSet是用来排序的,可以指定一个顺序,对象存入之后会按照指定的顺序排列
  • 使用方式
    • 自然顺序(comparable)

      • TreeSet类的add()方法中会把存入的对象提升为Comparable类型,存入的类必须实现Comparable接口,否则会报错
      • 调用对象的compareTo方法和集合中的对象比较
      • 根据compareTo()方法返回的结果进行存储
    • 比较器顺序(Comparator)

      • 创建TreeSet的时候可以指定一个Comparator
      • 如果传入了Comparator的子类对象,那么TreeSet就会按照比较器中的顺序排序
      • add()方法内部会自动调用Comparator接口中的compare()方法排序
      • 调用的对象时compare方法的第一个参数,集合中的对象时compare方法的第二个参数
    • 两种方式的区别

      • TreeSet构造函数什么都不传,默认按照类中Comparable的顺序(没有就报错ClassCastException)
      • TreeSet如果传入Comparator,就优先按照Comparator进行排序

17.16 集合框架(练习1)

  • 在一个集合中存储了无序并且重复的字符串,定义一个方法,让其有序(字典顺序),而且还不能去除重复
  • 思路:因为String本身就具备比较功能,但是重复不会保留,所以我们用比较器
  • 用匿名对象new Comparator<String>()

17.17 集合框架(练习2)

  • 从键盘接收一个字符串,程序对其中所有字符进行排序,例如edcba程序打印abcde
  • 思路:将字符串转换为字符数组,由于Character实现了comparable接口,所以还是要用比较器

1718 集合框架(练习3)

  • 从键盘接收多个整数,直到输入quit时结束输入,把所有输入的整数倒序排列打印
  • 8中基本数据类型包装类都实现了comparable接口
package com.kevin.test;

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

public class Test6 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        TreeSet<Integer> ts = new TreeSet<>(new Comparator<Integer>() {

            @Override
            public int compare(Integer i1, Integer i2) {
                
                int num = i2.compareTo(i1);
                return num == 0 ? 1 : num;
            }
            
        });
        
        while(true) {
            String line = sc.nextLine();
            if ("quit".equals(line)) {
                break;
            }
            
            Integer i = Integer.parseInt(line);
            ts.add(i);
        }
        
        for (Integer integer : ts) {
            System.out.println(integer);
        }
    }

}

17.19 键盘录入学生信息,按照总分排序

  • 分析
    • 封装学生类,重写toString方法,方便打印
    • 键盘录入需要Scanner
    • 创建TreeSet集合对象,在TreeSet的构造函数中传入比较器,按照总分比较
    • 录入5个学生,用集合的size是否小于5作为判断条件
    • 将录入的字符串用逗号切割,会返回一个字符串数组,从第二开始转换为int数

  • Student类
package com.kevin.bean;

public class Student {
    private String name;
    private int chinese;
    private int math;
    private int english;
    private int sum;
    public Student() {
        super();
        
    }
    public Student(String name, int chinese, int math, int english) {
        super();
        this.name = name;
        this.chinese = chinese;
        this.math = math;
        this.english = english;
        this.sum = this.chinese + this.math + this.english;
    }
    public int getSum() {
        return sum;
    }
    @Override
    public String toString() {
        
        return name +  "," + chinese + "," + math + "," + english + "," + sum;
    }
}

  • Test7类
package com.kevin.test;

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

import com.kevin.bean.Student;

public class Test7 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学生成绩格式是:姓名,语文成绩,数学成绩,英语成绩");
        TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {

            @Override
            public int compare(Student s1, Student s2) {
                int num = s2.getSum() - s1.getSum();
                return num == 0 ? 1 : num;
            }
            
        });
        while(ts.size() < 5) {
            String line = sc.nextLine();
            String[] arr = line.split(",");
            int chinese = Integer.parseInt(arr[1]);
            int math = Integer.parseInt(arr[2]);
            int english = Integer.parseInt(arr[3]);
            ts.add(new Student(arr[0], chinese, math, english));
        }
        System.out.println(" 排序后的学生信息:");
        for (Student student : ts) {
            System.out.println(student);
        }
    }
}

相关文章

网友评论

      本文标题:Topic17:Set集合

      本文链接:https://www.haomeiwen.com/subject/ueajjqtx.html