目录
- 集合
- 一、集合与数组
- 二、集合类体系结构
- 三、泛型(约定集合存储数据类型)
- 四、Collection集合常用API
- 五、Collection集合的遍历方式
- 5.1 迭代器遍历
- 5.2 增强for循环(for each):
- 5.3 lambda表达式
- 六、Collection集合存储自定义类型的对象
- 七、常见数据结构
集合
一、集合与数组
数组的特点:数组定义完成并启动后,类型确定、长度固定。
因此,在进行增删操作的时候,数组是不太合适的,可能需要放弃原有数组或者移位
弊端:
- 不适合元素的个数和类型不确定的业务场景
- 不适合做需要增删数据操作
- 数组的功能也比较的单一,处理数据的能力并不是很强大
因此,引入了集合。
集合是java中存储对象数据的一种容器
集合的特点:集合的大小不固定,启动后可以动态变化,类型也可以选择不固定。
优势:
- 集合非常适合元素个数不能确定,且需要做元素的增删操作的场景。
- 同时,集合提供的种类特别的丰富,功能也是非常强大的,开发中集合用的更多。
总结:
- 数组和集合的元素存储的个数问题。
- 数组定义后类型确定,长度固定
- 集合类型可以不固定,大小是可变的。
- 数组和集合存储元素的类型问题。
- 数组可以存储基本类型和引用类型的数据。
- 集合只能存储引用数据类型的数据。
- 数组和集合适合的场景
- 数组适合做数据个数和类型确定的场景。
- 集合适合做数据个数不确定,且要做增删元素的场景,集合种类更多,功能更强大。
二、集合类体系结构
集合:
- Collection单列集合,每个元素(数据)只包含一个值。
- Map双列集合,每个元素包含两个值(键值对)。
Collection集合特点
- List系列集合:添加的元素是有序、可重复、有索引。
- ArrayList、LinekdList :有序、可重复、有索引。
- Set系列集合:添加的元素是无序、不重复、无索引。
- HashSet: 无序、不重复、无索引
- LinkedHashSet: 有序、不重复、无索引。
- TreeSet:按照大小默认升序排序、不重复、无索引。
public class CollectionDemo1 {
public static void main(String[] args) {
//有序 可重复 有索引
Collection list=new ArrayList<>();
list.add("Java");
list.add("Java");
list.add("Mybatis");
list.add(12);
list.add(12);
list.add(false);
list.add(false);
System.out.println(list);//[Java, Java, Mybatis, 12, 12, false, false]
//无序 不重复 无索引
Collection list1=new HashSet();
list1.add("Java");
list1.add("Java");
list1.add("Mybatis");
list1.add(12);
list1.add(12);
list1.add(false);
list1.add(false);
System.out.println(list1);//[Java, false, 12, Mybatis]
}
}
三、泛型(约定集合存储数据类型)
集合都是泛型的形式,可以在编译阶段约束集合只能操作某种数据类型
Collection<String> lists = new ArrayList<String>();
Collection<String> lists = new ArrayList<>(); // JDK 7开始后面的泛型类型申明可以省略不写
注意:集合和泛型都只能支持引用数据类型,不支持基本数据类型,所以集合中存储的元素都认为是对象。
//Collection<int> lists = new ArrayList<>(); 错误写法
如果集合中要存储基本类型的数据怎么办?
// 存储基本类型使用包装类
Collection<Integer> lists1 = new ArrayList<>();
Collection<Double> lists2 = new ArrayList<>();
四、Collection集合常用API
Collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的。
五、Collection集合的遍历方式
方式一:迭代器
方式二:foreach/增强for循环
方式三:lambda表达式
5.1 迭代器遍历
迭代器遍历概述
- 遍历就是一个一个的把容器中的元素访问一遍。
- 迭代器在Java中的代表是Iterator,迭代器是集合的专用的遍历方式
public static void main(String[] args) {
Collection<String> list=new ArrayList<>();
list.add("String1");
list.add("String2");
list.add("String3");
list.add("String4");
System.out.println(list);//[String1, String2, String3, String4]
//1.得到当前集合的迭代器对象
Iterator<String> i= list.iterator();
//2.定义while循环
while (i.hasNext()){
String element=i.next();
System.out.println(element);
}
}
- Collection集合获取迭代器
- Iterator iterator():返回集合中的迭代器对象,该迭代器对象默认指向当前集合的0索引
- Iterator中的常用方法
- boolean hasNext():询问当前位置是否有元素存在,存在返回true ,不存在返回false
- E next():获取当前位置的元素,并同时将迭代器对象移向下一个位置,注意防止取出越界
迭代器如果取元素越界会出现什么问题
会出现NoSuchElementException异常
5.2 增强for循环(for each):
既可以遍历集合也可以遍历数组。
它是JDK5之后出现的,其内部原理是一个lterator迭代器,遍历集合相当于是迭代器的简化写法。
实现Iterable接口的类才可以使用迭代器和增强for,Collection接口已经实现了lterable接口。
格式:
for(元素数据类型 变量名 : 数组或者Collection集合) {
//在此处使用变量即可,该变量就是元素
}
例子
public static void main(String[] args) {
Collection<String> list=new ArrayList<>();
list.add("String1");
list.add("String2");
list.add("String3");
list.add("String4");
System.out.println(list);//[String1, String2, String3, String4]
//foreach 进行遍历
for (String element:list) {
System.out.println(element);
}
}
5.3 lambda表达式
Collection结合Lambda遍历的API:
default void forEach(Consumer<? super T> action): 结合lambda遍历集合
public static void main(String[] args) {
Collection<String> list=new ArrayList<>();
list.add("String1");
list.add("String2");
list.add("String3");
list.add("String4");
System.out.println(list);//[String1, String2, String3, String4]
//forEach 内部类
list.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
//ForEach lambda表达式
list.forEach((String s)->{System.out.println(s);});
//ForEach lambda表达式简化
list.forEach(s->System.out.println(s));
}
ForEach方法的底层代码:通过增强for实现
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
六、Collection集合存储自定义类型的对象
案列需求:某影院系统需要在后台存储上述三部电影,然后依次展示出来
分析
- 定义一个电影类
public class Movie {
private String name;
private double score;
private String actor;
public Movie(String name, double score, String actor) {
this.name = name;
this.score = score;
this.actor = actor;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public String getActor() {
return actor;
}
public void setActor(String actor) {
this.actor = actor;
}
}
- 定义一个集合存储电影对象。
- 创建3个电影对象,封装相关数据,把3个对象存入到集合中去。
- 遍历集合中的3个对象,输出相关信息。
public class TestDemo {
public static void main(String[] args) {
//定义一个集合存储电影对象。
Collection<Movie> movies=new ArrayList<>();
//创建3个电影对象,封装相关数据,把3个对象存入到集合中去。
movies.add(new Movie("《肖生克的救赎》", 9.7 , "罗宾斯"));
movies.add(new Movie("《霸王别姬》", 9.6 , "张国荣、张丰毅"));
movies.add(new Movie("《阿甘正传》", 9.5 , "汤姆.汉克斯"));
//遍历集合中的3个对象,输出相关信息。
for (Movie m:movies) {
System.out.println("片名"+m.getName());
System.out.println("评分"+m.getScore());
System.out.println("导演"+m.getActor());
}
}
}
集合中存储的是元素的什么信息?
集合中存储的是元素对象的地址。
七、常见数据结构
- 队列:先进先出,后进后出。
- 栈:后进先出,先进后出。
- 数组:内存连续区域,查询快,增删慢。
- 链表:元素是游离的,查询慢,首尾操作极快。
- 二叉树:永远只有一个根节点, 每个结点不超过2个子节点的树。
- 查找二叉树:小的左边,大的右边,但是可能树很高,查询性能变差。
- 平衡查找二叉树:让树的高度差不大于1,增删改查都提高了。
- 红黑树(就是基于红黑规则实现了自平衡的排序二叉树)