day17-集合框架(HashSet/TreeSet)

2017-01-23  本文已影响99人  苦笑男神

17.01_HashSet存储字符串并遍历

// Set集合,无索引,无重复数据,无序(存储不一致)
HashSet<String> set = new HashSet<>();
set.add("a");
set.add("a");         //因为set集合不能存储重复数据,所以这里存储失败,返回false
set.add("xxoo");

for (String string : set) {    //迭代,增强for
    System.out.println(string);
}

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

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + age;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    return result;
}
为什么Eclipe自动生成hashCode会选择31
1.31是一个质数,质数能被1和自身整除,减少重复性
2.31这个数不大也不小
3.31这个数好算,2的五次方-1,2向左移动5次减1

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

17.05_LinkedHashSet的概述和使用

//LinkedHashSet 底层是链表实现的,是Set集合中唯一一个能保证怎么存就怎么取的集合对象
//虽然存顺序和取顺序是一样的, 但是并没有索引
//因为HashSet的子类,所以也能保证元素是唯一的
LinkedHashSet<String> link = new LinkedHashSet<>();
link.add("a");
link.add("a");
link.add("b");
System.out.println(link);    // [a,b]

17.06_产生10个1-20之间的随机数要求随机数不能重复

需求:编写一个程序,获取10个1至20的随机数,要求随机数不能重复。并把最终的随机数输出到控制台。

HashSet<Integer> set = new HashSet<>();
Random random = new Random();
while (10 > set.size()) {
    set.add(random.nextInt(20) + 1);  //注意这里的随机数方法, +1是因为随机数方法是前闭后开的
}
System.out.println(set);    //这里也可以使用foreach循环输出

17.07_集合框架(练习)

Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
sc.close();
char[] arr = str.toCharArray();     //将字符串转换成字符数组
LinkedHashSet<Character> set = new LinkedHashSet<>();  //创建LinkedHashSet集合对象(为了跟输入顺序一致)
for (char c : arr) {
    set.add(c);
}
System.out.println(set);   //输入xxoo123,输出[x,o,1,2,3]

17.08_集合框架(练习)

// 将集合中的重复元素去掉
public static void getSingle(List<String> list) {
     LinkedHashSet<String> lhs = new LinkedHashSet<>();
     lhs.addAll(list);    //将list集合中的所有元素添加到lhs
     list.clear();       //清空原集合
     list.addAll(lhs);   //将去除重复的元素添回到list中
}

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

// 1.TreeSet能保证数据唯一,2.TreeSet是用来对元素排序的
TreeSet<Integer> ts = new TreeSet<>();
ts.add(3);
ts.add(2);
ts.add(2);
ts.add(1);
System.out.println(ts);   //输出 [1, 2, 3]

17.10_TreeSet存储自定义对象

TreeSet<Person> ts = new TreeSet<>();
ts.add(new Person("我日", 20));
ts.add(new Person("我2", 22));
ts.add(new Person("我xo", 80));

System.out.println(ts);

// 1. 直接存储,会运行报错
// 2. 想要不报错,Person类必须实现Comparable<T>接口
// 3.Comparable<T>接口的规律如下:
@Override
public int compareTo(Person o) {
     //当compareTo方法返回0 ,集合只有一个元素
     //当compareTo方法返回正数,集合怎么存,就怎么取
     //当compareTo方法返回负数,集合就会倒序
     int num = this.age - o.age ;  //年龄为主要条件,年龄一样比较姓名
     return num == 0 ? this.name.compareTo(o.name) : num;
}

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

TreeSet.png

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

TreeSet存储自定义对象并遍历练习1(按照姓名排序)
关键-->Person的compareTo方法
public int compareTo(Person o) {
     int num = this.name.compareTo(o.name);  //姓名是主要条件 
     return num == 0 ? this.age - o.age : num; //年龄是次要条件
}

// 字符串的比较,是比较字符串每个字符的Unicode值

17.14_TreeSet保证元素唯一和比较器排序的原理及代码实现

//匿名类 实现构造器
Comparator<String> com = new Comparator<String>() {
     @Override
     public int compare(String o1, String o2) {
          // 安装字符串长度比较
          int num = o1.length() - o2.length();
          return num == 0 ? o1.compareTo(o2) : num; //长度相同比较内容
     }
};

// 比较器排序  TreeSet有个传入构造器的构造方法
TreeSet<String> ts = new TreeSet<>(com);
ts.add("aabbcc");
ts.add("0125");
ts.add("c");
System.out.println(ts);

17.15_TreeSet原理

- TreeSet类的add()方法中会把存入的对象提升为Comparable类型
- 调用对象的compareTo()方法和集合中的对象比较
- 根据compareTo()方法返回的结果进行存储
- 创建TreeSet的时候可以制定 一个Comparator
- 如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的顺序排序
- add()方法内部会自动调用Comparator接口中compare()方法排序
- 调用的对象是compare方法的第一个参数,集合中的对象是compare方法的第二个参数
- TreeSet构造函数什么都不传, 默认按照类中Comparable的顺序(没有就报错ClassCastException)
- TreeSet如果传入Comparator, 就优先按照Comparator

17.16_集合框架(练习一)

ArrayList<String> list = new ArrayList<>();
list.add("ccc");
list.add("ccc");
list.add("aaa");
list.add("aaa");
list.add("bbb");
list.add("ddd");
list.add("ddd");

Comparator<String> com = new Comparator<String>() {  //匿名构造器
     @Override
     public int compare(String s1, String s2) {
          int num = s1.compareTo(s2);
          return num == 0 ? 1 : num;  //如果内容一样返回一个不为0的数字即可
     }
};

TreeSet<String> set = new TreeSet<>(com);
set.addAll(list);  //讲ArrayList的元素,一次性添加到TreeSet里面

list.clear();  //清空原来的ArrayList
list.addAll(set); //再将排序后的添加来
System.out.println(list);

17.17_集合框架(练习二)

Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
sc.close();
char[] arr = str.toCharArray();  //转为char[]数组

// 方法一
Arrays.sort(arr);           // Arrays排序
System.out.println(arr);    // 搞定

// 方法二 (使用TreeSet)
Comparator<Character> com = new Comparator<Character>() {
     @Override
     public int compare(Character c1, Character c2) {
          int temp = c1 - c2;     //自动拆箱
          return temp == 0 ? 1 : temp;
     }
};

TreeSet<Character> set = new TreeSet<>(com);
for (Character ch : arr) {  //其实这里Character和char都可以,自动装箱
     set.add(ch);
}
str = "";
for (Character character : set) {   //转字符串
     str += character;
}
System.out.println(str);

17.18_集合框架(练习三)

Scanner sc = new Scanner(System.in);

TreeSet<Integer> set = new TreeSet<>(new Comparator<Integer>() { //匿名类
     @Override 
     public int compare(Integer t1, Integer t2) {
          int num = t2 - t1 ;  //自动拆箱   使用t2.compareTo(t1)也可以
          return num == 0 ? 1 : num;
     }
});

while (true) {
     String str = sc.nextLine();
     //如果字符串常量和变量比较,常量放前面,这样不会出现空指针异常,变量里面可能存储null
     if ("quit".equals(str)) break; 
     set.add(Integer.valueOf(str));  //两个方法都可以:Integer.parseInt(str);
     // 其实这里应该加异常处理,后面会异常再讲
}

sc.close();
System.out.println(set);

17.19_键盘录入学生信息按照总分排序后输出在控制台

Scanner sc = new Scanner(System.in);
System.out.println("请输入5个学生成绩格式是:(姓名,语文成绩,数学成绩,英语成绩)");
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();
     try {
          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));
     } catch (Exception e) {
          System.out.println("录入格式有误,输入5个学生成绩格式是:(姓名,语文成绩,数学成绩,英语成绩");
     }
}
sc.close();
System.out.println(ts);

17.20_day17总结

END。
我是小侯爷。
在魔都艰苦奋斗,白天是上班族,晚上是知识服务工作者。
如果读完觉得有收获的话,记得关注和点赞哦。
非要打赏的话,我也是不会拒绝的。

上一篇 下一篇

猜你喜欢

热点阅读