集合体系结构
单列集合:
Collenction 每次只能添加一个值,其中红色是接口,蓝色是实现类
图来自黑马程序员网课
List系列集合:添加的元素是有序,可重复,有索引
Set系列集合:添加的元素是无序,不重复,无索引
双列集合:
Map:每次添加一对值
Collection集合
基础方法
Collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的
图来自黑马程序员网课
package com.lazyGirl.collectiondemo;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo1 {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<String>();
//要往List系列添加元素,始终为true
//要往Set系列添加元素,如果当前元素不存在,方法返回true
//否则返回false
coll.add("A");
System.out.println(coll);
coll.clear();
System.out.println(coll);
coll.add("B");
coll.add("C");
//若删除的元素不存在,remove返回false
//否则返回true
boolean flag = coll.remove("A");
System.out.println(flag);
//判断元素是否存在底层是使用equals方法进行判断的
//若集合存储的是自定义对象,也想通过contains方法判断是否包含,则需重写equals方法
boolean res = coll.contains("B");
System.out.println(res);
System.out.println(coll.isEmpty());
coll.add("hhh");
int size_coll = coll.size();
System.out.println(size_coll);
}
}
输出:
另外一个例子,关于contains()方法
package com.lazyGirl.collectiondemo;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo2 {
public static void main(String[] args) {
Collection<Studnet> coll = new ArrayList<>();
Studnet s1 = new Studnet("hh",12);
Studnet s2 = new Studnet("hhh",112);
Studnet s3 = new Studnet("hhhh",1112);
coll.add(s1);
coll.add(s2);
coll.add(s3);
Studnet s4 = new Studnet("hhhh",1112);
//因为contains方法在底层依赖于equals方法判断对象是否一致
//若存的是自定义对象,没有重写equals方法,则默认使用object类中的equals方法进行判断,
// 而object类中的equals方法是根据地址值判断的
boolean result = coll.contains(s4);
System.out.println(result);
}
}
输出:
Collection的遍历方式
迭代器遍历:
迭代器在Java中的类时Iterator,迭代器是集合专用的遍历方式
图来自黑马程序员网课
图来自黑马程序员
迭代器在遍历集合的时候是不依赖索引的,通过指针遍历
package com.lazyGirl.collectiondemo;
import java.sql.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo3 {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<>();
coll.add("A");
coll.add("B");
coll.add("C");
Iterator<String> it = coll.iterator();
while (it.hasNext()){
System.out.println(it.next());//获取元素并移动指针
}
// System.out.println(it.next());
//迭代器遍历完毕不会复位
System.out.println(it.hasNext());
Iterator<String> it2 = coll.iterator();
while (it2.hasNext()){
// System.out.println(it2.next());
// System.out.println(it2.next());
String s = it2.next();
if (s.equals("A")){
// coll.remove("A");
//迭代器遍历时,不能用集合的方法进行增加或者删除,如删除,使用迭代器提供的remove方法进行删除
it2.remove();
}
}
}
}
输出:
底层源码:
原理图:
图来自黑马程序员网课
图来自黑马程序员网课
增强for遍历:
增强for的底层就是迭代器,为了简化迭代器的代码书写的。
在JDK5以后出现的,其内部原理就是一个Iterator迭代器
所有的单列集合和数组才能用增强for循环遍历
格式:
for(元素的数据类型 变量名:数组或者集合){
}
//快捷键:集合名.for
for (String str : coll) {
System.out.println(str);
}
注意:
修改增强for中的变量,不会改变集合中原本的数据
package com.lazyGirl.collectiondemo;
import java.util.ArrayList;
import java.util.Collection;
public class EnhancedFor {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<>();
coll.add("A");
coll.add("B");
coll.add("C");
//快捷键:集合名.for
for (String str : coll) {
str = "111";
}
System.out.println(coll);
}
}
输出:
Lambda表达式遍历:
coll.forEach(s -> System.out.println(s));
package com.lazyGirl.collectiondemo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public class EnhancedFor {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<>();
coll.add("A");
coll.add("B");
coll.add("C");
//快捷键:集合名.for
for (String str : coll) {
str = "111";
}
System.out.println(coll);
coll.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
coll.forEach(s -> System.out.println(s)
);
}
}
输出:
总结:
Collection常见成员方法:add clear remove contains isEmpty size
三种通用的遍历方式:
迭代器:在遍历过程中需要删除元素,使用迭代器遍历
增强for lambda:只遍历
ArrayList集合
List集合的特有方法
- Collection的方法List都继承了
- List集合有索引,所以多了很多索引操作的方法
图来自黑马程序员网课
package com.lazyGirl.listdemo;
import java.util.ArrayList;
import java.util.List;
public class ListDemo1 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
System.out.println(list);
//在指定位置上添加元素,后面元素后移
list.add(1,"D");
System.out.println(list);
String a = list.remove(0);
System.out.println(a);
System.out.println(list);
List<Integer> lt1 = new ArrayList<Integer>();
lt1.add(1);
lt1.add(2);
lt1.add(3);
//删除元素时,如果出现方法重载,优先调用实参跟形参类型一致的方法
lt1.remove(1);
System.out.println(lt1);
//手动装箱,把基本数据类型的1变为Integer类型
Integer i = Integer.valueOf(1);
lt1.remove(i);
System.out.println(lt1);
lt1.add(4);
lt1.add(5);
//修改指定索引处的元素,返回被修改的元素
String res = list.set(0,"R");
System.out.println(res);
System.out.println(list);
System.out.println(list.get(0));
}
}
输出:
List集合的遍历方式
迭代器遍历
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListInterator {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
Iterator<Integer> it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
列表迭代器遍历
package com.lazyGirl.listdemo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class ListInterator {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
ListIterator<Integer> it2 = list.listIterator();
while (it2.hasNext()){
int temp = it2.next();
if (temp == 2){
it2.add(3);
}
}
System.out.println();
System.out.println(list);
}
}
输出:
增强for遍历
package com.lazyGirl.listdemo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListInterator {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
for (Integer i : list) {
System.out.print(i + " ");
}
}
}
Lambda表达式遍历
package com.lazyGirl.listdemo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListInterator {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.forEach(i -> System.out.print(i + " "));
}
}
普通for循环
package com.lazyGirl.listdemo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListInterator {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
for (int i = 0; i < list.size(); i++) {
int temp = list.get(i);
System.out.print(temp + " ");
}
}
}
五种 遍历方式对比:
迭代器遍历:在遍历过程中需要删除元素
列表迭代器:在遍历的过程中需要添加元素,
增强for以及Lambda表达式:仅遍历
普通for:遍历的时候想操作索引
底层原理
1. 利用空参创建的集合,在底层创建一个默认长度为0的数组
2. 添加第一个元素时,底层会创建一个新的长度为10的数组,这个数组的名字叫elementData
3. 存满时,会扩容1.5倍
4. 如果一次添加多个元素,1.5倍放不下,则新创建数组的长度以实际为准
图来自黑马程序员网课
数据结构概述
数据结构是计算机底层存储,组织数据的方式,指数据相互之间是以什么方式排列在一起的
数据结构(栈):先进后出(方法运行的时候进栈,执行完出栈)
数据结构(队列):先进先出
数据结构(数组):元素在内存中是连续存储的(删除元素较麻烦)
数据结构(链表):
链表中的结点是独立的对象,在内存中是不连续的,每个结点包含数据值和下一个结点的地址,链表查询慢,无论查询哪个数据都要从头开始找
图来自黑马程序员网课
LinkedList集合
- 底层数据结构是双链表,查询慢,增删快,但是如果操作的是收尾元素,速度也是极快的
- LinkedList本身多了很多直接操作收尾元素的特有API
图来自黑马程序员网课
LinkedList底层原理
图来自黑马程序员网课