文章目录
- 1、集合概述
- 2、集合类体系结构
- Collection集合体系
- 3、Collection集合常用API
- 3、Collection集合的遍历方式
- 方式一:迭代器
- 方式二:foreach/增强for循环
- 方式三:lambda表达式
- 4、List系列集合
- List集合特点和特有API
- LinkedList集合
- 5、集合的并发修改异常问题
- 6、Set系列集合
- 概述
- HashSet底层原理
- LInkedHashSet类
- TreeSet类
- 7、集合操作的工具类(Collections)
- 8、Map集合体系
- Map集合概述和使用
- Map集合体系
- Map常用API
- Map集合的遍历
- 方式一:键找值流程
- 方式二:键值对
- 方式三:Lambda
- 9、Stream流
- 获取Stream流
- Stream流常用API
- Stream流的收集操作
1、集合概述
- 集合和数组都是容器
数组的特点
数组
定义完成并启动后,类型确定
、长度固定
- 在进行增删改查操作的时候,数组是不太合适的,增删数据都需要放弃原有数组或者移位
- 数组适合的场景
- 当业务数据的个数是固定的,且都是同一批数据类型的时候,可以采取定义数组存储
- 集合是Java中存储对象数据的一种容器
集合的特点
- 集合的大小不固定,启动后可以动态变化,类型也可选择不固定
- 集合非常适合做元素的增删操作
注意:
集合中只能存储引用类型数据,如果要存储基本类型数据可以选用包装类- 集合适合的场景
- 数据的个数不确定,需要进行增删元素的时候
2、集合类体系结构
- Collection单列集合,每个元素(数据)只包含一个值
- Map双列集合,每个元素包含两个值(键值对)
Collection集合体系
Collection集合特点
List系列集合
:添加的元素是有序、可重复、有索引- ArrayList、LinekdList:有序、可重复、有索引
Set系列结合
:添加的元素是无序、不重复、无索引- HashSet:无序、不重复、无索引
- LinkedHasSet:
有序
、不重复、无索引 - TreeSet:
按照大小默认升序排序
、不重复、无索引
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开始后面的泛型类型申明可以省略不写
- 集合都是支持泛型的,可以在编译阶段约束集合只能操作某种数据类型
3、Collection集合常用API
Collection集合
- 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));
}
}
运行结果
3、Collection集合的遍历方式
方式一:迭代器
迭代器概述
- 遍历就是一个一个的把容器中的元素访问以便
- 迭代器在Java中的代表是
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());
}
}
}
运行结果
方式二:foreach/增强for循环
-
增强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);
}
}
}
运行结果
方式三:lambda表达式
- 得益于JDK8开始的新技术Lambda表达式,提供了一种更简单、更直接的遍历集合的方式
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);
});
}
}
运行结果
4、List系列集合
List集合特点和特有API
- ArrayList、LinekdList:有序、可重复、有索引
- 有序:存储和取出的元素顺序一致
- 可重复:存储的元素可以重复
- 有索引:可以通过索引操作元素
List的实现类的底层原理
- ArrayList底层是基于数组实现的:根据索引定位元素快,增删相对慢
- LinkedList底层基于双链表实现的:查询元素慢,增删首元素是非常快的
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集合
- 底层数据结构是双链表,查询慢,首尾操作的速度极快,所以多了很多首尾操作的特有API
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);
}
}
运行结果
5、集合的并发修改异常问题
- 当我们从集合中找出某个元素并删除的时候可能出现一种并发修改问题
Demo
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<String> 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);
}
}
那些遍历存在问题?
- 迭代器遍历集合且直接用集合删除元素的时候可能出现
- 增强for循环遍历集合且直接用集合删除元素的时候可能出现
哪种遍历且删除元素不出问题?
- 迭代器遍历集合但是用迭代器自己的删除方法操作可以解决
- 使用for循环遍历并删除不会存在这个问题
6、Set系列集合
概述
Set集合的功能基本上与Collection的API一致
Set系列集合特点
- 无序:存取顺序不一致
- 不重复:可以去除重复
- 无索引:没有带索引的方法,所以不能使用普通for循环遍历,不能通过索引来获取元素
Set集合实现类特点
- HashSet:无序、不重复、无索引
- LinkedHashSet:
有序
、不重复、无索引 - TreeSet:
排序
、不重复、无索引
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<String> 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);
}
}
运行结果
HashSet底层原理
- HashSet集合底层采取
哈希表
存储的数据 - 哈希表是一种对于增删改查数据性能都较好的结构
哈希表的组成
- JDK8之前,底层使用
数组+链表
组成 - JDK8开始后:底层采用
数组+链表+红黑树
组成
哈希值
- 是JDK根据对象的
地址
,按照某种规则算出来的int类型的数值
Object类的API
- public int hashCode():返回对象的哈希值
对象的哈希值特点
-
同一个对象多次调用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集合认为两个内容相同的对象是重复的应该怎么办?
- 重写对象的hashCode和equals方法
LInkedHashSet类
有序
、不重复、无索引- 这里的有序指的是保证存储和取出的元素顺序一致
- 底层数据结构依然是哈希表,只是每个元素又额外的多了一个双链表的机制记录存储的顺序
TreeSet类
- 不重复、无索引、
可排序
- 可排序:按照元素的大小默认升序(由小到大)排序
- TreeSet集合底层是基于
红黑树的数据结构
实现排序的,增删改查性能都较好 注意:TreeSet集合是一定要排序的,可以将元素按照指定的规则进行排序
TreeSet集合默认排序规则
- 对于数值类型:Integer,Double,官方默认按照大小进行升序排序
- 对于字符串类型:默认按照首字符的编号升序排序
- 对于自定义类型如Student对象,TreeSet无法直接排序
自定义排序规则
- TreeSet集合存储对象的时候有2种方式可以设计自定义比较规则
- 注意:如果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; });
7、集合操作的工具类(Collections)
Collections集合工具类
- java.utils.Collections:集合工具类
- 作用:Collections并不属于集合,是用来操作集合的工具类
Collections常用API
名称 | 说明 |
---|---|
public static <T> addAll(Collection<? super T> c,T … elements) | 把集合对象批量添加元素 |
public static void shuffle(List<?> list ) | 打乱List集合元素的顺序 |
public static <T> void sort(List<T> list ) | 将集合中元素按照默认规则排序 |
public static <T> void sort(List<T> list, Comparator<? super T> c ) | 将集合中元素按照指定的规则排序 |
8、Map集合体系
Map集合概述和使用
- Map集合是一种双列集合,每个元素包含两个数据
- Map集合的每个元素格式:key=value(键值对元素)
- Map集合也被称为“
键值对集合
” - Map结合的完整格式:{key1=value1,key2=value2,key3=value3,……}
Map集合体系
说明
使用最多的Map集合是HashMap
- 重点掌握HashMap,LinkedHashMap,TreeMap
Map集合体系特点
- Map集合的特点都是由键决定的
- Map集合的键是无序,不重复,无索引,值不做要求(可以重复)
- Map集合后面重复的键对应的值会覆盖前面重复键的值
- Map集合的键值对都可以为null
Map集合实现类特点
- HashMap:元素按照键是无序,不重复,无索引,值不做要求
- Demo
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); } }
- 运行结果
- Demo
- LinkedHashMap:元素按照键是
有序
,不重复,无索引,值不做要求- Demo
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); } }
- 运行结果
- Demo
- TreeMap:元素按照键是
排序
,不重复,无索引,值不做要求
Map常用API
Map集合
- 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() | 集合的长度,也就是集合中键值对的个数 |
Map集合的遍历
方式一:键找值流程
- 先获取Map集合的全部键的Set集合
- 遍历键的Set集合,然后通过提取对应值
键找值涉及到的API
名称 | 说明 |
---|---|
Set<K> keySet() | 获取所有键的集合 |
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);
}
}
}
运行结果
方式二:键值对
- 先把Map集合转换成Set集合,Set集合中每个元素都是键值对实体类型
- 遍历Set集合,然后提取键以及提取值
键值对涉及到的API
名称 | 说明 |
---|---|
Set<Map,Entry<K,V> entrySet() | 获取所有键值对对象的集合 |
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);
}
}
}
运行结果
方式三:Lambda
- 得益于JDK8开始的新技术Lambda表达式,提供了一种更简单,更直接的遍历集合的方式
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);
});
}
}
运行结果
9、Stream流
- 在Java8中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream流概念
- 目的:用于简化集合和数组操作的API
获取Stream流
集合获取Stream流
名称 | 说明 |
---|---|
default Stream<E> stream() | 获取当前集合对象的Stream流 |
数组获取Stream流的方式
名称 | 说明 |
---|---|
public static <T> Steam<T> stream(T[] array) | 获取当前数组的Stream流 |
public static<T> Stream<T> of(T…values) | 获取当前数组/可变数据的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流常用API
名称 | 说明 |
---|---|
Stream<T> filter(Predicate<? super T> predicate) | 用于对流中的数据进行 过滤 |
Stream<T> limit(long maxSize) | 获取前几个元素 |
Stream<T> skip(long n) | 跳过前几个元素 |
Stream<T> distinct | 去除流中重复的元素(依赖hashCode和equals方法) |
static <T> Stream concat(Stream a,Stream b) | 合并a和b两个流为一个流 |
- 中间方法也称为非终结方法,调用完成后返回新的Stream流可以继续使用,支持链式编程
- 在Stream流中无法直接修改集合、数组中的数据
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流操作后的结果数据转回到集合或者数组中去
Stream流的收集方法
名称 | 说明 |
---|---|
R collect(Collector collector) | 开始收集Stream流,指定收集器 |
Collectors工具类提供了具体的收集方式
名称 | 说明 |
---|---|
public static <T> Collector toList() | 把元素收集到List集合中 |
public static <T> Collector toSet() | 把元素收集到Set集合中 |
public static <T> Collector toMap(Function keyMapper,Function valueMapper) | 把元素收集到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);
}
}
运行结果