目录
集合体系结构
Collection集合
List集合
ArrayList集合
LinkedList集合
集合体系结构
注意:有序:存进去的数组和取出来时一样 而不是大小的那种有序
Collection集合
单列集合顶层接口Collection
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
//注意点:Collection是一个接口 不能创建他的对象
//所以我们学习他的方法时,只能创建实现类的对象
//实现类:ArrayList
//多态的方式创建元素
//目的:1为了学习Collection接口里面的方法
//自己在做一些练习的时候,还是按照之前的方式去创建对象
Collection<String>coll=new ArrayList<>();
//1.添加元素
//细节:如果我们要往List系列集合中添加元素,那么方法用于返回true,因为List系列的是允许元素重复的
//如果当前要添加的元素不存在,方法返回true,表示添加成功
//如果当前要添加的元素已经存在 方法返回false,表示添加失败.
//因为Set系列的集合不允许重复
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
System.out.println(coll);
//coll.clear();
// System.out.println(coll);
//删除
//细节一:因为Collection里面定义的是共性的方法,所以此时不能通过索引进行删除,只能通过元素的对象进行删除.
//细节二:方法会有一个布尔类型的返回值,删除成功返回true,删除失败返回false
//如果要删除的元素不存在,就会删除失败
coll.remove("aaa");
System.out.println(coll);
//判断元素是否包含
//细节:底层是依赖equals方法进行判断是否存在的
//所以,如果集合中存储的是自定义对象,也想通过contains方法来判断是否包含,那么在javabean类中,一定要重写equals方法
boolean result=coll.contains("aaa");
System.out.println(result);
//判断是否为空
boolean empty = coll.isEmpty();
//获取集合长度
int size = coll.size();
}
}
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
//alt+insert hashCode() equals()
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
// @Override
// public int hashCode() {
// return Objects.hash(name, age);
// }
}
import java.util.ArrayList;
import java.util.Collection;
public class Demo1 {
public static void main(String[] args) {
//1.创建集合对象
Collection<Student>coll=new ArrayList<>();
//2.创建三个学生对象
Student s1=new Student("yjy",18);
Student s2=new Student("yyy",20);
Student s3=new Student("jjj",19);
//3.把学生对象添加到集合当中
coll.add(s1);
coll.add(s2);
coll.add(s3);
//4.判断集合中某个学生对象是否包含
Student s4=new Student("yjy",18);
//如果同姓名和同年龄,就认为是一个学生
//因为存的是自定义对象,没有重写equals方法,那么默认使用Object类中的equals方法进行判断,而Object类中
//equals方法,依赖地址值进行判断
//我们的需求:如果同姓名和同年龄,就认为是一个学生
//所以需要在自定义的Javabean中对equals方法进行重写
boolean i = coll.contains(s4);
System.out.println(i);//true
}
}
Collection的遍历方式
不能用普通for来遍历了 因为set系列用不了 只有List系列能够用
三种方式:
迭代器遍历
特点:迭代器不依赖索引的
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
//1.创建集合并添加元素
Collection<String>coll=new ArrayList<>();
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
coll.add("ddd");
coll.add("eee");
//2.获取迭代器对象
Iterator<String>it=coll.iterator();
//3.利用循环不断地去获取集合中的每一个元素
while(it.hasNext()){
//4.next方法的两件事情:获取元素并移动指针
//System.out.println(it.next());//aaa ccc eee
// System.out.println(it.next());//bbb ddd 此时循环还没有结束
//System.out.println(str);
String str = it.next();
System.out.println(str);
if("bbb".equals(str)){
// coll.remove("bbb");
//不能用集合的方法来删除 要用迭代器的方法
it.remove();
}
}
System.out.println(coll);
//ConcurrentModificationException
//当上面的循环结束之后,迭代器的指针已经指向了最后没有元素的位置
//System.out.println(it.next());//.NoSuchElementException
//迭代器异常指针是不会复位的
//System.out.println(it.hasNext());//false
//如果我们要继续第二次遍历结合,只能再次获取一个新的迭代器对象
// Iterator<String> it2 = coll.iterator();
// while(it2.hasNext()){
// String str = it2.next();
// System.out.println(str);
// }
}
}
增强for遍历
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
//增强for遍历
//1.创建集合并添加元素
Collection <String>coll=new ArrayList<>();
coll.add("yjy");
coll.add("yyy");
coll.add("jjj");
//利用增强for进行遍历
//注意点:
//s 其实就是一个第三方变量,在循环的过程中依次表示集合中的每一个元素
// for(String s :coll){
// System.out.println(s);
// }
//快捷方式:coll.for
for (String s : coll) {
s="qqq";
}
System.out.println(coll);//yjy yyy jjj qqq qqq qqq 结果发现没有改变
//修改增强for中的变量,不会改变集合中原本的数据
}
}
Lambda表达式遍历
import java.util.ArrayList;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
//1.创建集合并添加元素
Collection<String>coll=new ArrayList<>();
coll.add("yjy");
coll.add("yyy");
coll.add("jjj");
//2.利用匿名内部类方式进行遍历
//底层原理:
//其实也会自己遍历集合,依次得到每一个元素
//把得到的每一个元素,传递给下面accept方法
//s依次表示集合中的每一个元素
// coll.forEach(new Consumer<String>() {
// @Override
// //s依次表示集合中的每一个数据
// public void accept(String s) {
// System.out.println(s);
// }
// });
//Lambda表达式
//()->{}
coll.forEach(s-> System.out.println(s));
}
}
List集合
public class Demo1 {
public static void main(String[] args) {
//list系列集合中的两个删除的方法
//1.直接删除元素
//2.通过索引进行删除
//1.创建集合并添加元素
List<Integer>list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
//2.删除元素
//请问此时删除的元素是1还是1索引上的元素?
//因为在调用方法的时候,如果方法出现了重载现象
//优先调用,实参跟形参类型一致的那个方法
list.remove(1);
System.out.println(list);
//手动装箱,手动把基本数据类型的1,变成Integer类型
Integer i =Integer.valueOf(1);
list.remove(i);
System.out.println(list);
}
}
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
//1.创建一个集合-->它是一个接口 要创建实现类对象
List<String>list=new ArrayList<>();
//2.添加元素
list.add("aaa");
list.add("bbb");
list.add("ccc");
//细节:把元素添加在指定的索引处 原来索引上的元素会依次往后移动
// list.add(1,"qqq");
// System.out.println(list);
// String remove = list.remove(0);
//String result = list.set(0, "111");
//System.out.println(result);
String s = list.get(0);
System.out.println(s);
//3.打印集合
System.out.println(list);
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Test {
public static void main(String[] args) {
//1.创建集合并创建对象 因为List是一个接口 所以要用多态的方式创建对象
List<String>list=new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//1.迭代器
// Iterator<String>it=list.iterator();
// while(it.hasNext()){
// String str = it.next();
// System.out.println(str);
// }
//2.增强for
// for (String s : list) {
// System.out.println(s);
// }
//3.Lambda表达式
// list.forEach(s-> System.out.println(s));
//4.普通for
//size get
// for (int i = 0; i < list.size(); i++) {
// String s = list.get(i);
// System.out.println(s);
// }
//5.列表迭代器
//获取一个列表迭代器的对象 里面的指针默认指向0索引
//额外添加了一个方法 在遍历的过程中 可以添加元素
ListIterator<String> it = list.listIterator();
while(it.hasNext()){
String str = it.next();
if("bbb".equals(str)){
//qqq
it.add("qqq");
}
System.out.println(str);
}
}
}
数据结构(栈 队列 数组 链表)
栈:先进后出
队列:先进先出
数组:
链表:
ArrayList集合
查看ArrayList的源码->ctrl+n ->alt+7 会出现大纲/ctrl+f12
LinkedList集合
泛型深入
//当我在编写一个类的时候,如果不确定类型,那么这个类就可以定义为泛型类
//泛型类的书写
import java.util.Arrays;
public class MyArrayList<E>{
Object[] obj = new Object[10];
int size;
// E:不确定的类型 该类型在类名后面已经定义过了
//e:形参的名字,变量名
public boolean add(E e){
obj[size]=e;
size++;
return true;
}
public E get(int index){
return (E)obj[index];
}
@Override
public String toString() {
return Arrays.toString(obj);
}
}
public class Test {
public static void main(String[] args) {
//使用泛型类
MyArrayList<String>list =new MyArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
System.out.println(list);
MyArrayList<Integer>list2=new MyArrayList<>();
list2.add(123);
list2.add(456);
list2.add(789);
String s = list.get(0);
System.out.println(s);
System.out.println(list2);
}
}
import java.util.ArrayList;
public class ListUtil {
private ListUtil(){}
//类中定义一个静态方法addALL,用来添加多个集合的元素
/*
* 参数一:集合
* 参数二~最后:要添加的元素
*
* */
public static<E> void addALL(ArrayList<E>list,E e1, E e2,E e3){
list.add(e1);
list.add(e2);
list.add(e3);
}
// public static<E> void addALL(ArrayList<E>list,E...e){
// for (E e1 : e) {
// list.add(e1);
// }
//
// }
}
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
ArrayList<String>list=new ArrayList<>();
ListUtil.addALL(list,"aaa","bbb","ccc");
System.out.println(list);
// ArrayList<Integer>list2=new ArrayList<>();
// ListUtil.addALL(list2,1,2,3,12,3,3);
// System.out.println(list2);
}
}
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
//泛型不具备继承性,但是数据具备继承性
//创建集合的对象
ArrayList<Ye> list1 = new ArrayList<>();
ArrayList<Fu> list2 = new ArrayList<>();
ArrayList<Zi> list3 = new ArrayList<>();
//调用method方法
// method(list1);
// method(list2);
// method(list3);
list1.add(new Ye());
list1.add(new Fu());
list1.add(new Zi());
}
/*
* 此时泛型里面写的是什么类型 那么只能传递什么类型的数据
*
* */
public static void method(ArrayList<Ye> list) {
}
}
import java.util.ArrayList;
public class demo2 {
public static void main(String[] args) {
/*需求:定义一个方法,形参是一个集合,但是集合中的数据类型不确定
*
* */
ArrayList<Ye> list1 = new ArrayList<>();
ArrayList<Fu> list2 = new ArrayList<>();
ArrayList<Zi> list3 = new ArrayList<>();
ArrayList<Student2>list4=new ArrayList<>();
method(list1);
method(list2);
method(list3);
method(list4);
}
/*
* 此时泛型里面写的是什么类型 那么只能传递什么类型的数据
*
* */
//利用泛型方法有一个小弊端 此时他可以接收任意的数据类型
//希望是不确定类型 但是我希望只传递ye fu zi
//此时就可以使用泛型通配符
//? 也表示不确定的类型
//它可以进行类型的限定
//?extends E:表示可以传递E或者E所有的子类类型
//?super E:表示可以传递E或者E所有的父类类型
public static<E> void method(ArrayList<E> list) {
}
}
//
class Ye {
}
//
class Fu extends Ye {
}
class Zi extends Ye {
}
class Student2{}
/*
* 此时泛型里面写的是什么类型 那么只能传递什么类型的数据
*
* */
//利用泛型方法有一个小弊端 此时他可以接收任意的数据类型
//希望是不确定类型 但是我希望只传递ye fu zi
//此时就可以使用泛型通配符
//? 也表示不确定的类型
//它可以进行类型的限定
//?extends E:表示可以传递E或者E所有的子类类型
//?super E:表示可以传递E或者E所有的父类类型
/*
* 应用场景:
* 1.如果我们在定义类,方法,接口的时候,如果类型不确定,就可以定义泛型类,泛型方法,泛型接口
* 2.如果类型不确定,但是能知道以后只能传递某个继承体系中,就可以用泛型通配符
* 泛型的通配符:
* 关键点:可以限定类型的范围.
*
* */
public static void method(ArrayList<? extends Ye> list) {
}
如果 name 和 age不确定可以这样做
public class Aniaml<N,I> {
private N name;
private I age;
}
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
ArrayList<PersianCat>list1=new ArrayList<>();
ArrayList<LihuaCat>list2=new ArrayList<>();
ArrayList<TeddyDog>list3=new ArrayList<>();
ArrayList<HuskyDog>list4=new ArrayList<>();
keepPet(list1);
keepPet(list2);
keepPet(list3);
keepPet(list4);
}
// public static void keepPet(ArrayList<?extends Cat>list){
// //遍历集合 调用动物的eat方法
// }
// public static void keepPet(ArrayList<?extends Dog>list){
// //遍历集合 调用动物的eat方法
// }
public static void keepPet(ArrayList<?extends Aniaml>list){
//遍历集合 调用动物的eat方法
}
}
public class TeddyDog extends Dog{
@Override
public void eat() {
System.out.println("一只叫做"+getName()+"的"+getAge()+"岁的泰迪,正在吃骨头,边吃边蹭");
}
}
public class PersianCat extends Cat{
@Override
public void eat() {
System.out.println("一只叫做"+getName()+"的"+getAge()+"岁的波斯猫,正在吃小饼干");
}
}
public class LihuaCat extends Cat{
@Override
public void eat() {
System.out.println("一只叫做"+getName()+"的"+ getAge() +"岁的狸花猫,正在吃鱼");
}
}
public class HuskyDog extends Dog{
@Override
public void eat() {
System.out.println("一只叫做"+getName()+"的"+getAge()+"岁的哈士奇,正在吃骨头,边吃边拆家");
}
}
public abstract class Dog extends Aniaml{
}
public abstract class Aniaml {
private String name;
private int age;
public Aniaml() {
}
public Aniaml(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "Aniaml{name = " + name + ", age = " + age + "}";
}
public abstract void eat();
}
public abstract class Cat extends Aniaml{
//1.继承抽象类 重写里面的所有的抽象方法
//2.本身Cat也是抽象的,让Cat的子类再重写重写方法
//此时采取第二种处理方案
//因为猫的两个子类中eat的方法体还是不一样的.
}
数据结构(树)
平衡二叉树的旋转机制
数据结构(红黑树,红黑规则,添加节点处理方案详解)
Set系列集合
public class Test {
public static void main(String[] args) {
//存储字符串并遍历
//利用set系列的集合,添加字符串,并使用多种方式遍历
//1.迭代器
//2.增强for
//3.Lambda表达式
//1.创建一个set集合的对象 set是一个接口 要创建它实现类的对象
Set<String>s=new HashSet<>();//多态形式创建\
//2.添加元素
//如果当前元素是第一次添加 那么可以添加成功 返回true
//如果当前元素是第二次添加 返回false
boolean r1 = s.add("zhangsan");
boolean r2 = s.add("zhangsan");
// s.add("yyy");//无序
//无索引
System.out.println(r1);//true
System.out.println(r2);//false
System.out.println(s);//[zhansan]
// Iterator<String> it = s.iterator();
// while(it.hasNext()){
// String str = it.next();
// System.out.println(str);
// }
//增强for
// for (String str : s) {
// System.out.println(str);
// }
//Lambda表达式
s.forEach((str)-> System.out.println(str));
}
}
HashSet
public class Test {
public static void main(String[] args) {
//哈希值
//1.创建对象
Student s1 =new Student("张三",23);
Student s2 =new Student("张三",23);
//2.如果没有重写hashCode方法,不同对象计算出的哈希值是不同的
System.out.println(s1.hashCode());//495053715
System.out.println(s2.hashCode());//1922154895
//但是在Student类中重写了hashCode()之后计算出的哈希值就会变成一样了
System.out.println("abc".hashCode());//string类里面已经重写了
System.out.println("acD".hashCode());
//这两个值一样 小概率一样 哈希碰撞
import java.util.HashSet;
public class Test {
public static void main(String[] args) {
//利用HashSet集合去除重复元素
//需求:创建一个存储学生对象的集合,
// 存储多个学生对象.使用程序实现控制台遍历该集合
//要求:学生对象的成员变量值相同,我们就认为是同一个对象
//1.创建三个学生对象
//String Integer 里面java已经重写好了
Student s1=new Student("zhangsan",23);
Student s2=new Student("lisi",24);
Student s3=new Student("wangwu",25);
Student s4=new Student("zhangsan",23);
//2.创建集合用来添加学生 hashset去重 student重写
HashSet<Student>hs=new HashSet<>();
//3.添加元素
System.out.println(hs.add(s1));
System.out.println(hs.add(s2));
System.out.println(hs.add(s3));
System.out.println(hs.add(s4));
//4.打印集合
System.out.println(hs);
}
}
LinkedHashSet
import java.util.LinkedHashSet;
public class Test {
public static void main(String[] args) {
//1.创建四个学生对象
Student s1 =new Student("zhangsan",23);
Student s2 =new Student("lisi",24);
Student s3 =new Student("wangwu",25);
Student s4 =new Student("zhangsan",23);
//2.创建集合对象
LinkedHashSet<Student>lhs =new LinkedHashSet<>();
//3.添加元素
System.out.println(lhs.add(s1));
System.out.println(lhs.add(s2));
System.out.println(lhs.add(s3));
System.out.println(lhs.add(s4));
//4.打印集合
System.out.println(lhs);
}
}
TreeSet
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
//需求:利用TreeSet存储整数并排序
//1.创建TreeSet集合对象
TreeSet<Integer>ts =new TreeSet<>();
//2.添加元素
ts.add(5);
ts.add(2);
ts.add(1);
ts.add(4);
ts.add(3);
//3.打印集合
System.out.println(ts);//[1, 2, 3, 4, 5]
//4.遍历集合(三种遍历方式)
//迭代器
// Iterator<Integer> it = ts.iterator();
// while(it.hasNext()){
// Integer i =it.next();
// System.out.println(i);
// }
//增强for
// for (Integer t : ts) {
// System.out.println(t);
// }
//Lambda
// ts.forEach(i-> System.out.println(i));
}
}
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;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
@Override
//this:当前要添加
//o:当前在红黑树中的元素
public int compareTo(Student o) {
//指定排序规则
//只看年龄 升序
int result = this.getAge() - o.getAge();
System.out.println("this:"+this);
System.out.println("o:"+o);
return result;
}
}
import java.util.Comparator;
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
//1.创建集合
//o1:表示当前要添加的元素
//o2:表示已经在红黑树存在的元素
//返回值的规则跟之前是一样的
TreeSet<String>ts=new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
//按照长度
int i = o1.length() - o2.length();
//如果一样长 按照首字母进行排序
i=i==0?o1.compareTo(o2):i;
return i;
}
});
//2.添加元素
//string里面写了第一种排序方法 但是仍然不满足要求
//所以此时使用第二种排序方法
ts.add("c");
ts.add("ab");
ts.add("df");
ts.add("qwer");
System.out.println(ts);
}
}
public class Student implements Comparable<Student>{
private String name;
private int age;
private int chinese;
private int math;
private int English;
public Student() {
}
public Student(String name, int age, int chinese, int math, int English) {
this.name = name;
this.age = age;
this.chinese = chinese;
this.math = math;
this.English = English;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
/**
* 获取
* @return chinese
*/
public int getChinese() {
return chinese;
}
/**
* 设置
* @param chinese
*/
public void setChinese(int chinese) {
this.chinese = chinese;
}
/**
* 获取
* @return math
*/
public int getMath() {
return math;
}
/**
* 设置
* @param math
*/
public void setMath(int math) {
this.math = math;
}
/**
* 获取
* @return English
*/
public int getEnglish() {
return English;
}
/**
* 设置
* @param English
*/
public void setEnglish(int English) {
this.English = English;
}
public String toString() {
return "Student{name = " + name + ", age = " + age + ", chinese = " + chinese + ", math = " + math + ", English = " + English + "}";
}
@Override
public int compareTo(Student o) {
int sum1 = this.getEnglish()+this.getChinese()+this.getMath();
int sum2 = o.getEnglish()+o.getChinese()+o.getMath();
int i = sum1 - sum2;
//如果总分一样 就按照语文成绩排序
i=i==0?this.getChinese()-o.getChinese():i;
//如果语文成绩一样 就按照数学成绩排序
i=i==0?this.getMath()-o.getMath():i;
//如果数学成绩一样 就按照英语成绩排序(可省略不写)
i=i==0?this.getEnglish()-o.getEnglish():i;
//如果英文成绩一样 就按照年龄排序
i=i==0?this.getAge()-o.getAge():i;
//如果年龄一样,就按照姓名的字母顺序进行排序
i=i==0?this.getName().compareTo(o.getName()):i;
return 0;
}
}
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
//创建学生对象
Student s1 =new Student("zhangsan",23,90,99,50);
Student s2 =new Student("lisi",24,90,98,50);
Student s3 =new Student("wangwu",26,60,99,50);
//创建对象
//默认ArrayList
//数据唯一 Hashset
唯一加排序 TreeSet
TreeSet<Student>ts =new TreeSet<>();
ts.add(s1);
ts.add(s2);
ts.add(s3);
System.out.println(ts);
}
}
综合案例使用场景
源码分析
需要先学习Map