选择排序
/**
* @author 刘涛
* @date 2022/8/22 9:49
*
* List集合去重
* 1)新建集合思想
* 2)如果不让你新建集合,如何完成?
* 创建一个旧集合,添加一堆重复的字符串数据
* 遍历旧集合,间接的 利用"选择排序的思想"
* 使用0角标对应的元素依次和后面的元素进行比较(equals()),如果后面的元素和前面的元素一致,
* 将后面的元素,从集合中干掉(remove(Object)),角标应该--,结束;
*
*
* 使用这种完成存自定义类型
* List<Student> ---存储Student类型,
* 保证Student类型需要重写Object的hashCode和equals()
*/
public class Test1 {
public static void main(String[] args) {
//创建一个旧集合
List<String> list = new ArrayList<>() ;
//添加重复的字符串元素
list.add("hello") ;
list.add("world") ;
list.add("hello") ;
list.add("javaee") ;
list.add("javaee") ;
list.add("world") ;
list.add("Javaee") ;
list.add("python") ;
list.add("python") ;
//利用选择排序的思想
for(int x = 0 ; x < list.size()-1; x++){//比较的次数
for(int y = x+1; y<list.size(); y ++){//将后面的元素一一遍历出来
//使用list.get(x)前的元素和list.get(y)进行比较,如果一致,将后面的元素干掉,角标--
if(list.get(x).equals(list.get(y))){
list.remove(y) ;
y-- ;
}
}
}
//增强for遍历集合
for(String s:list){
System.out.println(s);
}
}
}
集合嵌套
import java.util.ArrayList;
/**
* @author 刘涛
* @date 2022/8/22 10:01
* 有三个java基础班,每一个java基础班ArrayList<Student>
* 然后将每一个基础班存入4个学生,大的集合是ArrayList<ArrayList<Student>>,进行遍历
*
* 获取学生信息
*
* 分析:
* 1)有一个大的集合:里面有3个小的集合-都是ArrayList<Student>
* 创建一个大的集合ArrayList<ArrayList<Student>>
* 2)分别创建四个小的集合,给里面添加学生信息
* 3)在将每一个小的ArrayList<Student>存储到的集合中
* 4)增强for遍历大的集合 ,然后在遍历小集合
*
*/
public class Test2 {
public static void main(String[] args) {
//先创建一个的集合
ArrayList<ArrayList<Student>> bigArray = new ArrayList<>() ;
//分别创建小的集合
//第一个java基础班
ArrayList<Student> array1 = new ArrayList<>() ;
//添加两个学生
Student s1 = new Student("瞎子",25) ;
Student s2 = new Student("ez",26) ;
Student s3 = new Student("螳螂",20) ;
//添加
array1.add(s1) ;
array1.add(s2) ;
array1.add(s3) ;
//将array1添加到大集合中
bigArray.add(array1) ;
//第二个java基础班
ArrayList<Student> array2 = new ArrayList<>() ;
//创建三个学生
Student s4 = new Student("宋江",35) ;
Student s5 = new Student("卢俊义",32) ;
Student s6 = new Student("武大郎",40) ;
array2.add(s4) ;
array2.add(s5) ;
array2.add(s6) ;
//将第二个集合添加到大集合中
bigArray.add(array2) ;
//第三个java基础班
ArrayList<Student> array3 = new ArrayList<>() ;
//创建三个学生
Student s7 = new Student("曹操",45) ;
Student s8 = new Student("周瑜",20) ;
Student s9 = new Student("刘备",30) ;
array3.add(s7) ;
array3.add(s8) ;
array3.add(s9) ;
//将第三个集合添加到大集合中
bigArray.add(array3) ;
// ArrayList<ArrayList<Student>> bigArray = new ArrayList<>() ; //大集合
for(ArrayList<Student> array :bigArray){
//里面的小的集合泛型:Student
for(Student s:array){
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
}
Set
Set集合的特点:保证元素唯一,而且不能保证迭代次序
唯一,无序性(元素不重复,不能保证顺序—哈希表(key-value键值对)完成的(桶状结构))
HashSet
为什么保证元素能唯一的:
HashSet底层依赖于Map<K,V>接口的子实现类HashMap<K,V>实现的
- HashSet的add()方法依赖于HashMap的put 方法,这个方法间接依赖于Object类的equals和hashCode()
String类型,String底层已经重写了hashCode()和equals方法
- HashCode:比较字符串的哈希码值(理解为地址值)是否一样,如果一样,比较内容是否一样
英文可以,但是中文,繁写字体或简写字体,hashCode一样,内容可能不一样;必须重写equals,比较内容是否相容!
- HashSet如果存储的是自定义对象,必须自定义的类要重写Object类的equals和hashCode(),否则不是唯一的
TreeSet
Set集合的子实现类
底层数据结构是一个红黑树结构,(自平衡的二叉树结构)
依赖于TreeMap<K,V>实现的, 可以完成自然排序以及比较器排序,取决于我们使用的构造方法
- public TreeSet() :无参构造方法:完成一种自然排序,前提:存储的数据类型必须要实现Compareable接口里面的compareTo方法
- public TreeSet(Comparator comparator):有参构造方法实现比较器排序:存储的类型必须要实现comparator接口里面的compare()方法
public TreeSet():无参构造 自然排序
import java.util.TreeSet;
/**
* @author 刘涛
* @date 2022/8/22 11:25
* 集合的TreeSet<Student> 自定义对象,如何进行排序(自然排序--->TreeSet的无参构造方法)
* 按照学生的年龄从小到大排序
* 学生的姓名和年龄
*
* 一般这种:告诉你的排序主要条件,你自己分析次要条件
* 主要条件:年龄从小到大,
* 次要条件:年龄相等的,就是同一个人吗?,年龄相等还要判断姓名是否一样
* Student s1 = new Student("gaoyuanyuan",36) ;
* Student s2 = new Student("zhangjianing",36) ;
*/
public class TreeSetTest {
public static void main(String[] args) {
//自然排序--->TreeSet的无参构造方法
//自定义类型
//TreeSet集合:set集合的一种:元素唯一,而且按照条件要排序的 (排序条件:主要/次要)
TreeSet<Student> ts = new TreeSet<>() ;
//创建一些学生对象
Student s1 = new Student("gaoyuanyuan",36) ;
Student s2 = new Student("gaoyuanyuan",36) ;
Student s3 = new Student("zhangjianing",36) ;
Student s4 = new Student("zhangsan",20) ;
Student s5 = new Student("wenzhang",19) ;
Student s6 = new Student("wenzhang",25) ;
Student s7 = new Student("mayili",43) ;
Student s8 = new Student("yaodi",30) ;
Student s9 = new Student("mayili",43) ;
//添加集合
ts.add(s1) ;
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;
ts.add(s8) ;
ts.add(s9) ;
//遍历
for(Student s:ts){
System.out.println(s.getName()+"---"+s.getAge());
}
/**
* 要实现自然排序,使用TreeSet集合的无参构造方法,
* 那么TreeSet<E>,里面的泛型E类型,必须要实现一个接口Compareable接口,
* 重写接口的comareTo方法,否则无法进行自然排序;意味着如果TreeSet<Student>,
* 自定义类型,那么Student这个类必须要实现Comareable接口,否则报错;
*/
}
------------------------------------------------------
//学生类
//要实现自然 排序:自定义的类型要实现自然排序的接口:Comareable
public class Student implements Comparable<Student>{
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 String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
/**
* 要进行比较的具体的方法 ,就模拟Integer类 jdk 提供的也实现了 Comareable接口完成数字的排序 里面使用三元运算符
* @param s
* @return
*/
@Override
public int compareTo(Student s) { //s就是要传进来的学生对象 s1-s9 s1就是根节点
//主要条件就是按照学生的年龄从小到大
int num =this.age - s.age ;// this.age:当前类对象的地址值引用的学生年龄使用根节点-存进来的学生的年龄的
//年龄从大到小
// int num = s.age -this.age;
//次要条件:年龄相同的:不一定就是同一个人
//年龄如果是0,说明上面的年龄相等,比较姓名是否一样,姓名(英文):String类型重写了comareable方法,实现了comareTo方法,按照字典顺序比较
int num2 = (num==0)?this.name.compareTo(s.name):num; //年龄相等,按照姓名比较,不相等;按照年龄从小打大
return num2;
}
}
public TreeSet(Comparator comparator): 有参构造 比较器排序
/**
*TreeSet<Student>存储的这个学生,姓名和年龄,主要条件:按照学生的姓名的长度从小到大比较?(使用比较器排序完成)
* //长度一样,姓名内容可能不一样,比较姓名内容;
* // 姓名内容一样,比较年龄是否一样
* //Student s1 = new Student("zyyzabc",35) ;
* //Student s2 = new Student("liushishi",35) ;
* //Student s3 = new Student("fenqing",35) ;
* //Student s4 = new Student("fenqing",38) ;
*/
public class TreeSetTest3 {
public static void main(String[] args) {
//创建TreeSet集合对象,有参构造方式,完成比较器排序
TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
//主要条件:按照学生的姓名的长度从小到大比较 排序
int num = s1.getName().length() - s2.getName().length() ;
//长度一样,不一定是同一个人,还要比较:姓名的内容是否一样,按照字典比较
int num2 = (num==0)?s1.getName().compareTo(s2.getName()):num;
//长度一样,姓名也一样,比较年龄是否一样(年龄从小到大)
int num3 = (num2==0)?s1.getAge()-s2.getAge():num2;
return num3;
}
}) ;
//创建学生对象
Student s1 = new Student("gaoyuanyuan",43) ;
Student s2 = new Student("gaoyuanyuan",43) ;
Student s3 = new Student("zhangsanfen",43) ;
Student s4 = new Student("zhangsanfen",25) ;
Student s5 = new Student("liushishi",35) ;
Student s6 = new Student("wanglihong",30) ;
Student s7 = new Student("liushishi",35) ;
Student s8 = new Student("wuqilong",20) ;
Student s9 = new Student("wangwuwu",50) ;
ts.add(s1) ;
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;
ts.add(s8) ;
ts.add(s9) ;
//遍历
for(Student s:ts){
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
-----------------------------------------------------------
//学生类
public class Student {
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 String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}