数组的特点
数组
定义完成并启动后,类型确定
、长度固定
集合的特点
注意:
集合中只能存储引用类型数据,如果要存储基本类型数据可以选用包装类List系列集合
:添加的元素是有序、可重复、有索引
Set系列结合
:添加的元素是无序、不重复、无索引
有序
、不重复、无索引按照大小默认升序排序
、不重复、无索引Demo
package collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
public class CollectionDemo1 {
public static void main( String[] args ) {
//有序 可重复 有索引
Collection list = new ArrayList();
list.add("java");
list.add("java");
list.add("Mybatis");
list.add(123);
list.add(true);
list.add(123.5);
list.add(false);
list.add(false);
System.out.println(list);
//无序 不重复 无索引
Collection set = new HashSet();
set.add("java");
set.add("java");
set.add("Mybatis");
set.add(123);
set.add(true);
set.add(123.5);
set.add(false);
set.add(false);
System.out.println(set);
}
}
Collection<String> list = new ArrayList<String>();
Collection<String> list = new ArrayList<>(); //从JDK1.7开始后面的泛型类型申明可以省略不写
Collection集合
Collection API
名称 | 说明 |
---|---|
public boolean add(E e) | 把给定的对象添加到当前集合中 |
public void clear() | 清空集合中所有的元素 |
public boolean remove(E e) | 把给定的对象在当前集合中删除 |
public boolean contains(Object ob) | 判断当前集合中是否包含给定的对象 |
public boolean isEmpty() | 判断当前集合是否为空 |
public int size() | 返回集合中元素的个数 |
public Object[] toArray() | 把结合汇总元素,存储到数组中 |
Demo
package collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class CollectionDemo2 {
public static void main( String[] args ) {
Collection<String> list = new ArrayList<>();
// 1.添加元素,添加成功返回true
list.add("java");
list.add("MySQL");
list.add("HTMl");
list.add("HTMl");
list.add("java");
list.add("xiaowu");
System.out.println(list);
// 2.清空集合元素
/*list.clear();
System.out.println(list);*/
// 3.判断集合是否为空,为空返回true
System.out.println(list.isEmpty());
// 4.获取集合的大小
System.out.println(list.size());
// 5.判断集合中是否包含某个元素
System.out.println(list.contains("java")); //true
System.out.println(list.contains("Java")); //false
// 6.删除某个元素:如果有多个重复元素默认删除前面第一个
System.out.println(list.remove("Java")); //false
System.out.println(list);
System.out.println(list.remove("java")); //true
System.out.println(list);
// 7.把集合转换成数组 [MySQL, HTMl, HTMl, java, xiaowu]
Object[] arrs = list.toArray();
System.out.println("数组:"+ Arrays.toString(arrs));
}
}
迭代器概述
Iterator
,迭代器是集合的专用遍历方式Collection集合获取迭代器
名称 | 说明 |
---|---|
Iterator iterator() |
返回集合中的迭代器对象,该迭代器对象默认指向当前集合的0索引 |
Iterator中的常用方法
名称 | 说明 |
---|---|
boolean hasNext() | 询问当前位置是否有元素存在,存在返回true,不存在返回false |
E next() | 获取当前位置的元素,并同时将迭代器对象移向下一个位置,注意防止取出越界 |
Demo
package collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo3 {
public static void main( String[] args ) {
Collection<String> list = new ArrayList<>();
list.add("java");
list.add("html");
list.add("js");
list.add("vue");
System.out.println(list);
// 1. 得到当前的迭代器对象
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
增强for循环:既可以遍历集合也可以遍历数组
它是JDK5之后出现的,其内部原理是一个Iterator迭代器,遍历集合相当于是迭代器的简化写法
实现Iterable接口的类才可以使用迭代器和增强for,Collection接口已经实现了Iterable接口
格式
for(元素数据类型 变量名 : 数组或者Collection集合){
//在此处使用变量即可,该变量就是元素
}
Demo
package collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo3 {
public static void main( String[] args ) {
Collection<String> list = new ArrayList<>();
list.add("java");
list.add("html");
list.add("js");
list.add("vue");
System.out.println(list);
for (String s : list) {
System.out.println(s);
}
}
}
Collection结合Lambda遍历的API
名称 | 说明 |
---|---|
default void forEach(Consumer super T> action | 结合lambda比遍历集合 |
Demo
package collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Consumer;
public class CollectionDemo3 {
public static void main( String[] args ) {
Collection<String> list = new ArrayList<>();
list.add("java");
list.add("html");
list.add("js");
list.add("vue");
System.out.println(list);
list.forEach(s->{
System.out.println(s);
});
}
}
List的实现类的底层原理
List集合特有方法
List集合因为支持索引,所以多了很多索引操作的独特API,其他Collection的功能List也都继承了
package list;
import java.util.ArrayList;
import java.util.List;
public class ListDemo1 {
public static void main( String[] args ) {
List<String> list = new ArrayList<>();
list.add("java");
list.add("java");
list.add("html");
list.add("html");
list.add("mysql");
list.add("mysql");
// 在索引位置插入元素
list.add(2,"小吴");
System.out.println(list);
// 根据索引删除元素
list.remove(1);
System.out.println(list);
// 根据索引获取元素
System.out.println(list.get(1));
// 修改索引位置处的元素
list.set(1,"小吴在敲Bug");
System.out.println(list);
}
}
LinkedList集合的特有功能
名称 | 说明 |
---|---|
public void addFirst(E e) | 在该列表开头插入指定的元素 |
public void addLast(E e) | 将指定的元素追加到此列表的末尾 |
public E getFirst() | 返回此列表中的第一个元素 |
public E getLast() | 返回此列表中的最后一个元素 |
public E removeFirst() | 从此列表中删除并返回第一个元素 |
public E removeLast() | 从此列表中删除并返回最后一个元素 |
Demo
package list;
import java.util.LinkedList;
public class ListDemo2 {
public static void main( String[] args ) {
// LinkedList可以完成队列结构,和栈结构(双列表)
// 1.做一个队列
LinkedList<String> queue = new LinkedList<>();
queue.addLast("1号");
queue.addLast("2号");
queue.addLast("3号");
System.out.println(queue);
// 出队
System.out.println(queue.removeFirst());
System.out.println(queue);
// 2.做一个栈
LinkedList<String > stack = new LinkedList<>();
// 入栈
stack.push("第1颗子弹");
stack.push("第2颗子弹");
stack.push("第3颗子弹");
stack.push("第4颗子弹");
System.out.println(stack);
//出栈
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack);
}
}
package update_delete;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Test {
public static void main( String[] args ) {
// 1. 准备数据
List<String> list = new ArrayList<>();
list.add("java");
list.add("html");
list.add("html");
list.add("css");
list.add("js");
list.add("Linux");
System.out.println(list);
/**
* 需求:删除全部的html信息
*/
// 1.迭代器
/*Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String ele = iterator.next();
if("html".equals(ele)){
//删除html
//list.remove(ele); //集合删除会出毛病
iterator.remove(); //删除迭代器所在位置的元素值(没毛病)
}
}*/
// 2.foreach遍历删除(会出现问题,无法解决的,fareach不能边遍历边删除,会出现Bug)
/*for (String s : list) {
if("html".equals(s)){
list.remove(s);
}
}*/
// 3.lambda表达式(会出现问题,无法解决的,lambda不能边遍历边删除,会出现Bug)
/*list.forEach(s->{
if("html".equals(s)){
list.remove(s);
}
});*/
// 4.for循环(边遍历边删除集合没毛病,但是必须从后面开始遍历删除才不会漏掉应该删除的元素)
for (int i = list.size()-1; i >=0 ; i--) {
String ele = list.get(i);
if("html".equals(ele)){
list.remove(ele);
}
}
System.out.println(list);
}
}
那些遍历存在问题?
哪种遍历且删除元素不出问题?
Set集合的功能基本上与Collection的API一致
Set系列集合特点
Set集合实现类特点
有序
、不重复、无索引排序
、不重复、无索引Demo
package set;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
public class SetDemo1 {
public static void main( String[] args ) {
// 看看Set系列集合的特点:HashSet LinkedHashSet TreeSet
Set<String> sets = new HashSet<>();// 无序 不重复 无索引
//Set sets = new LinkedHashSet<>(); //有序 不重复 无索引
sets.add("Java");
sets.add("Java");
sets.add("HTML");
sets.add("HTML");
sets.add("CSS");
sets.add("CSS");
sets.add("Linux");
sets.add("Linux");
System.out.println(sets);
}
}
哈希表
存储的数据哈希表的组成
数组+链表
组成数组+链表+红黑树
组成哈希值
地址
,按照某种规则算出来的int类型的 数值
Object类的API
对象的哈希值特点
同一个对象多次调用hashCode()方法返回的哈希值是相同的
默认情况下,不同对象的哈希值是不同的
Demo
package set;
public class SetDemo2 {
public static void main( String[] args ) {
String name = "小吴在敲Bug";
System.out.println(name.hashCode());
System.out.println(name.hashCode());
String name1 = "小吴";
System.out.println(name1.hashCode());
System.out.println(name1.hashCode());
}
}
哈希表的详细流程
1. 创建一个默认长度16,默认加载为0.75数组,数组名table
2. 根据元素的焊锡值跟数组的长度求余计算出应存入的位置
3. 判断当前位置是否为null,如果是null直接存入,如果位置不为null,表示有元素,则调用equals方法比较属性值,如果一样,则不存,如果不一样,则存入数组
4. 当数组存满到16*0.75=12时,就自动扩容,每次扩容原先的两倍
如果希望Set集合认为两个内容相同的对象是重复的应该怎么办?
有序
、不重复、无索引可排序
红黑树的数据结构
实现排序的,增删改查性能都较好注意:TreeSet集合是一定要排序的,可以将元素按照指定的规则进行排序
TreeSet集合默认排序规则
自定义排序规则
默认使用集合自带的比较器排序
方式一
让自定义类(如学生类)实现Comparable接口
重写里面的 compareT
o 方法 来定制比较规则
public class Student implements Comparable<Student> {
private String name;
private int age;
private char sex;
/**
* 方式一:类自定义比较规则
*
* @param o
* @return
*/
@Override
public int compareTo( Student o ) {
//按照年龄进行比较
return this.age - o.age >= 0 ? 1 : -1;
}
}
方式二
TreeSet集合有参数构造器,可以设置Comparator接口对应的比较器对象,来定制比较规则
// 方式二:集合自带比较器对象进行规则定制
Set<Student> studentSet = new TreeSet<>(( Student s1, Student s2 ) -> {
return s2.getAge() - s1.getAge() >= 0 ? 1 : -1;
});
Collections集合工具类
Collections常用API
名称 | 说明 |
---|---|
public static |
把集合对象批量添加元素 |
public static void shuffle(List> list ) |
打乱List集合元素的顺序 |
public static List ) |
将集合中元素按照默认规则排序 |
public static List ) |
将集合中元素按照指定的规则排序 |
键值对集合
”使用最多的Map集合是HashMap
Map集合体系特点
Map集合实现类特点
package map;
import java.util.HashMap;
import java.util.Map;
public class MapDemo1 {
public static void main( String[] args ) {
// 1.创建一个Map集合对象
Map<String,Integer> maps = new HashMap<>();//一行经典代码
maps.put("鸿星尔克",3);
maps.put("鸿星尔克",5);
maps.put("键盘",2);
maps.put("Java从入门到砸键盘",1);
maps.put(null,null);
System.out.println(maps);
}
}
有序
,不重复,无索引,值不做要求
package map;
import java.util.LinkedHashMap;
import java.util.Map;
public class MapDemo1 {
public static void main( String[] args ) {
// 1.创建一个Map集合对象
Map<String,Integer> maps = new LinkedHashMap<>();//一行经典代码
maps.put("鸿星尔克",3);
maps.put("鸿星尔克",5);
maps.put("键盘",2);
maps.put("Java从入门到砸键盘",1);
maps.put(null,null);
System.out.println(maps);
}
}
排序
,不重复,无索引,值不做要求Map集合
Map API如下
名称 | 说明 |
---|---|
V put(K key,V value) | 添加元素 |
V remove(Object key) | 根据键删除值对元素 |
void clear() | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合是否包含指定的键 |
boolean containsValue(Object value) | 判断集合是否包含指定的值 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中键值对的个数 |
键找值涉及到的API
名称 | 说明 |
---|---|
Set |
获取所有键的集合 |
V get(Object key) | 根据键获取值 |
Demo
package map;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo2 {
public static void main( String[] args ) {
Map<String, Integer> maps = new HashMap<>();
// 添加元素
maps.put("娃娃", 30);
maps.put("iphoneX", 100);
maps.put("huawei", 1000);
maps.put("生活用品", 10);
maps.put("手表", 10);
System.out.println(maps); // {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}
// 1.键找值,第一步,先拿到集合的全部键
Set<String> keys = maps.keySet();
// 2.遍历每个键,根据键提取值
for (String key : keys) {
int value = maps.get(key);
System.out.println(key + "=====>" + value);
}
}
}
键值对涉及到的API
名称 | 说明 |
---|---|
Set | 获取所有键值对对象的集合 |
K getKey() | 获得键 |
K getValue() | 获取值 |
Demo
package map;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo3 {
public static void main( String[] args ) {
Map<String, Integer> maps = new HashMap<>();
// 添加元素
maps.put("娃娃", 30);
maps.put("iphoneX", 100);
maps.put("huawei", 1000);
maps.put("生活用品", 10);
maps.put("手表", 10);
System.out.println(maps); // {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}
// 1.把Map集合转换成Set集合
Set<Map.Entry<String, Integer>> entries = maps.entrySet();
// 2.开始遍历
for (Map.Entry<String, Integer> entry : entries) {
String key = entry.getKey();
int value = entry.getValue();
System.out.println(key+"=====>"+value);
}
}
}
Map结合Lambda遍历的API
名称 | 说明 |
---|---|
default void forEach(BiConsumer< ? super K,? super V> action) | 结合Lambda遍历Map集合 |
Demo
package map;
import java.util.HashMap;
import java.util.Map;
public class MapDemo4 {
public static void main( String[] args ) {
Map<String, Integer> maps = new HashMap<>();
// 添加元素
maps.put("娃娃", 30);
maps.put("iphoneX", 100);
maps.put("huawei", 1000);
maps.put("生活用品", 10);
maps.put("手表", 10);
System.out.println(maps); // {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}
maps.forEach((key,value)->{
System.out.println(key+"====>"+value);
});
}
}
集合获取Stream流
名称 | 说明 |
---|---|
default Stream |
获取当前集合对象的Stream流 |
数组获取Stream流的方式
名称 | 说明 |
---|---|
public static |
获取当前数组的Stream流 |
public static |
获取当前数组/可变数据的Stream流 |
Demo
package stream;
import java.util.*;
import java.util.stream.Stream;
public class StreamDemo1 {
public static void main( String[] args ) {
// Collection集合获取流
Collection<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
// Map集合获取流
Map<String,Integer> maps = new HashMap<>();
// 键流
Stream<String> keyStram = maps.keySet().stream();
// 值流
Stream<Integer> valueStram = maps.values().stream();
// 键值对
Stream<Map.Entry<String, Integer>> keyAndValueStream = maps.entrySet().stream();
// 数组获取流
String[] names={"Java","HTML","CSS","Vue"};
//方式一
Stream<String> nameStream1 = Arrays.stream(names);
//方式二
Stream<String> nameStream2 = Stream.of(names);
}
}
名称 | 说明 |
---|---|
Stream |
用于对流中的数据进行 过滤 |
Stream |
获取前几个元素 |
Stream |
跳过前几个元素 |
Stream |
去除流中重复的元素(依赖hashCode和equals方法) |
static |
合并a和b两个流为一个流 |
Demo
package stream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
public class StreamDemo2 {
public static void main( String[] args ) {
List<String> list = new ArrayList<>();
Collections.addAll(list,"Java","HTML","Css",
"Vue","JavaScript","JavaSE","JavaSE");
list.stream().filter(s -> s.startsWith("J")).forEach(s -> System.out.println(s));
long count = list.stream().filter(s -> s.length() == 3).count();
System.out.println(count);
list.stream().filter(s-> s.startsWith("J")).limit(2).forEach(s-> System.out.println(s));
list.stream().filter(s-> s.startsWith("J")).skip(2).forEach(s-> System.out.println(s));
//Map加工方法
//给集合元素的前面加上 小吴在学
list.stream().map((item)-> "小吴在学"+item).forEach(s-> System.out.println(s));
Stream<String> s1 = list.stream().filter(s -> s.startsWith("J"));
Stream<String> s2 = Stream.of("Css1", "Css2");
Stream<String> s3 = Stream.concat(s1, s2);
s3.forEach(s-> System.out.println(s));
}
}
收集Stream流的含义
:就是把Stream流操作后的结果数据转回到集合或者数组中去Stream流的收集方法
名称 | 说明 |
---|---|
R collect(Collector collector) | 开始收集Stream流,指定收集器 |
Collectors工具类提供了具体的收集方式
名称 | 说明 |
---|---|
public static |
把元素收集到List集合中 |
public static |
把元素收集到Set集合中 |
public static |
把元素收集到Map集合中 |
Demo
package stream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamDemo3 {
public static void main( String[] args ) {
List<String> list = new ArrayList<>();
Collections.addAll(list,"Java","HTML","Css",
"Vue","JavaScript","JavaSE","JavaSE");
Stream<String> jStream = list.stream().filter(s -> s.startsWith("J"));
List<String> jList = jStream.collect(Collectors.toList());
System.out.println(jList);
}
}