集合框架
Set
Set集合概述及特点
- 可通过API查看
- 无序(存储和取出的顺序)和唯一(元素不允许重复)
HashSet存储字符串并遍历
import java.util.HashSet;
public class MyTest {
public static void main(String[] args) {
HashSet<String> str = new HashSet<>();
str.add("a");
str.add("aa");
str.add("aa");
str.add("aaa");
str.add("aaaa");
for (String s : str) {
System.out.println(s);
//aa
//aaa
//a
//aaaa
}
}
}
// HashSet:底层数据结构是哈希表(JDK1.7 数组+链表 JDK1.8 优化 数组+链表+红黑树)
//元素无序(存取元素的顺序不一致)且唯一(元素不允许重复)
//HashSet集合保证元素的唯一性,是靠元素重新hashCode和equals()方法来保证的,如果元素不重写,则无法保证元素的 唯一性。
HashSet保证元素唯一性
- HashSet 底层数据结构是哈希表
- HashSet 不是线程安全的,集合元素可以是 null
- 哈希表:是一个元素为链表的数组,综合了数组和链表的优点 (像新华字典一样) (JDK1.7之前)
当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的hashCode 值,然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。
HashSet 集合判断两个元素相等的标准:
两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。
结论:HashSet 保证元素唯一性是靠元素重写hashCode()和equals()方法来保证的,如果不重写则无法保证。
HashSet存储自定义对象保证元素唯一性
import java.util.HashSet;
public class MyTest {
public static void main(String[] args) {
HashSet<Student> students = new HashSet<>();
students.add(new Student("鹿秀儿", 22));
students.add(new Student("鹿秀儿", 22));
students.add(new Student("鹿秀", 22));
students.add(new Student("鹿秀儿", 19));
for (Student student : students) {
System.out.println(student);
//Student{name='鹿秀儿', age=22}
//Student{name='鹿秀', age=22}
//Student{name='鹿秀儿', age=19}
}
}
}
HashSet存储自定义对象保证元素唯一性图解及代码优化
代码优化:为了减少比较,优化hashCode()代码写法。最终版就是自动生成即可
HashSet存储自定义对象并遍历练习
import java.util.HashSet;
import java.util.Iterator;
import java.util.function.Consumer;
public class MyTest {
public static void main(String[] args) {
HashSet<Student> students = new HashSet<>();
students.add(new Student("鹿秀儿", 22));
students.add(new Student("鹿秀儿", 22));
students.add(new Student("鹿秀", 22));
students.add(new Student("鹿秀儿", 19));
//for方法遍历
for (Student student : students) {
System.out.println(student);
//Student{name='鹿秀儿', age=22}
//Student{name='鹿秀', age=22}
//Student{name='鹿秀儿', age=19}
}
//forEach遍历
students.forEach(new Consumer<Student>() {
@Override
public void accept(Student student) {
System.out.println(student.getName() + "==" + student.getAge());
//鹿秀儿==22
//鹿秀==22
//鹿秀儿==19
}
});
//迭代器遍历
Iterator<Student> iterator = students.iterator();
while (iterator.hasNext()){
Student next = iterator.next();
System.out.println(next);
//Student{name='鹿秀儿', age=22}
//Student{name='鹿秀', age=22}
//Student{name='鹿秀儿', age=19}
}
}
}
LinkedHashSet的概述和使用
数据结构有两个:
- 链表(保证有序)(按照添加的顺序)
- 哈希表(保证元素唯一)
LinkedHashSet的概述:元素有序,并且唯一
import java.util.LinkedHashSet;
public class MyTest {
public static void main(String[] args) {
LinkedHashSet<Integer> integers = new LinkedHashSet<>();
integers.add(44);
integers.add(26);
integers.add(85);
integers.add(54);
integers.add(86);
integers.add(23);
integers.add(77);
for (Integer integer : integers) {
System.out.print(integer+"\t");
//与录入顺序一致
//44 26 85 54 86 23 77
}
}
}
TreeSet存储Integer类型的元素并遍历
TreeSet集合的特点:
-
元素唯一,并且可以对元素进行排序
-
排序:
自然排序
使用比较器排序
-
具体使用哪一种排序取决于构造方法
import java.util.TreeSet;
public class MyTest {
public static void main(String[] args) {
TreeSet<Integer> integers = new TreeSet<>();
integers.add(20);
integers.add(18);
integers.add(23);
integers.add(22);
integers.add(17);
integers.add(24);
integers.add(19);
integers.add(18);
integers.add(24);
for (Integer integer : integers) {
System.out.print(integer+"\t");
//17 18 19 20 22 23 24
}
}
}
//注意:使用TreeSet集合进行元素的自然排序,那么对元素有要求,要求这个元素必须实现Comparable接口 否则无法进行自然排序
//保证元素的唯一性是靠compareTo方法的返回值来确定如果返回0 表示两个元素相等则不重复存储
TreeSet保证元素唯一和自然排序的原理和图解
二叉树的数据结构
先存入一个树根,分两个叉,存储元素时,跟树根比较,小的放在左边,大的放在右边
如果相等就不存储,取的时候按照左中右的顺序来取
TreeSet存储自定义对象并遍历练习1
import java.util.TreeSet;
public class MyTest {
public static void main(String[] args) {
TreeSet<Student> students = new TreeSet<>();
students.add(new Student("鹿秀儿", 18));
students.add(new Student("路遥知", 17));
students.add(new Student("赵天笑", 24));
students.add(new Student("笑", 24));
students.add(new Student("赵天笑", 24));
students.add(new Student("大雄", 13));
for (Student student : students) {
System.out.println(student);
//Student{name='大雄', age=13}
//Student{name='路遥知', age=17}
//Student{name='鹿秀儿', age=18}
//Student{name='笑', age=24}
//Student{name='赵天笑', age=24}
}
}
}
public class Student implements Comparable{
private String name;
private int age;
public Student() {
}
public Student(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 int compareTo(Object o) {
Student s= (Student) o;
//先比较年龄
int a=this.age-s.age;
//再比较姓名
int b=(a==0)?this.name.compareTo(s.name):a;
return b;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
TreeSet存储自定义对象并遍历练习2
import java.util.TreeSet;
public class MyTest {
public static void main(String[] args) {
TreeSet<Student> students = new TreeSet<>();
students.add(new Student("鹿秀儿", 18));
students.add(new Student("路遥知", 17));
students.add(new Student("赵天笑", 24));
students.add(new Student("笑", 24));
students.add(new Student("赵天笑", 24));
students.add(new Student("大雄", 13));
for (Student student : students) {
System.out.println(student);
//Student{name='笑', age=24}
//Student{name='大雄', age=13}
//Student{name='路遥知', age=17}
//Student{name='鹿秀儿', age=18}
//Student{name='赵天笑', age=24}
}
}
}
public class Student implements Comparable{
private String name;
private int age;
public Student() {
}
public Student(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 int compareTo(Object o) {
Student s= (Student) o;
//先比较名字长度
int a=this.name.length()-s.name.length();
//再比较年龄
int b=(a==0)?this.age-s.age:a;
//最后比较姓名
int c=(b==0)?this.name.compareTo(s.name):b;
return c;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
产生10个1-20之间的随机数要求随机数不能重复
import java.util.HashSet;
import java.util.TreeSet;
public class MyTest {
public static void main(String[] args) {
//HashSet不重复
HashSet<Integer> hashSet = new HashSet<>();
for(;;){
hashSet.add((int) (Math.random()*20+1));
if (hashSet.size()>=10){
break;
}
}
System.out.println(hashSet);
//TreeSet不重复并且排序
TreeSet<Integer> treeSet = new TreeSet<>();
for (; ; ) {
treeSet.add((int) (Math.random()*20+1));
if(treeSet.size()>=10){
break;
}
}
System.out.println(treeSet);
}
}
import java.util.HashSet;
public class MyTest {
public static void main(String[] args) {
HashSet<Integer> hashSet = new HashSet<>();
//while循环判断集合长度
while(hashSet.size()<10){
hashSet.add((int) (Math.random()*20+1));
}
System.out.println(hashSet);
}
}
键盘录入学生信息按照总分排序后输出在控制台
import java.util.Scanner;
import java.util.TreeSet;
import java.util.function.Consumer;
public class MyTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("输入学生个数");
int n = sc.nextInt();
TreeSet<Student> students = new TreeSet<>();
for (int i = 1; i <= n; i++) {
Student s = new Student();
System.out.println("输入第" + i + "个学生姓名");
String name = sc.next();
s.setName(name);
System.out.println("输入"+name+"的语文成绩");
int ch = sc.nextInt();
s.setChineseScore(ch);
System.out.println("输入"+name+"的数学成绩");
int ma= sc.nextInt();
s.setMathScore(ma);
System.out.println("输入"+name+"的英语成绩");
int en = sc.nextInt();
s.setEnglishScore(en);
s.setZongfen(ch+ma+en);
students.add(s);
}
System.out.println("姓名" + '\t' + "语文" + '\t' + "数学" + '\t' + "英语" + '\t' + "总分");
students.forEach(new Consumer<Student>() {
@Override
public void accept(Student student) {
System.out.println(student);
}
});
}
}
public class Student implements Comparable {
private String name;
private int chineseScore;
private int mathScore;
private int englishScore;
private int zongfen;
public Student() {
}
public Student(String name, int chineseScore, int mathScore, int englishScore, int zongfen) {
this.name = name;
this.chineseScore = chineseScore;
this.mathScore = mathScore;
this.englishScore = englishScore;
this.zongfen = zongfen;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChineseScore() {
return chineseScore;
}
public void setChineseScore(int chineseScore) {
this.chineseScore = chineseScore;
}
public int getMathScore() {
return mathScore;
}
public void setMathScore(int mathScore) {
this.mathScore = mathScore;
}
public int getEnglishScore() {
return englishScore;
}
public void setEnglishScore(int englishScore) {
this.englishScore = englishScore;
}
public int getZongfen() {
return zongfen;
}
public void setZongfen(int zongfen) {
this.zongfen = zongfen;
}
@Override
public int compareTo(Object o) {
Student student = (Student) o;
//先根据总分排序
int a = student.zongfen - this.zongfen;
int b = (a == 0) ? student.chineseScore - this.chineseScore : a;
int c = (b == 0) ? student.mathScore - this.mathScore : b;
int d = (c == 0) ? student.englishScore - this.englishScore : c;
int e = (d == 0) ? student.name.compareTo(this.name) : d;
return e;
}
@Override
public String toString() {
return name + '\t' + chineseScore + '\t' + mathScore + '\t' + englishScore + '\t' + zongfen;
}
}
完