- 能够掌握Lambda表达式的标准格式与省略格式(重点)
作用:简化函数式接口的匿名内部类
()->{}
(参数)->{重写接口中的抽象方法的方法体}
(int a,int b)->{}==>省略数据类型 (a,b)->{}
(int a)->{}==>省略数据类型 a->{}
a->{只有一行代码}==>a->代码(return ; {} 一起省略)
- 能够通过集合、映射或数组方式获取流(重点)
Collection集合中方法default Stream<E> stream()直接把集合转换为Stream流
ArrayList<Integer> list = new ArrayList<>();
Stream<Integer> stream1 = list.stream();
Stream接口中的静态方法static <T> Stream<T> of(T... values) 把数组转换为Stream流
Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8);
String[] arr1 = {"a", "b", "c"};
Stream<String> stream3 = Stream.of(arr1);
- 能够掌握常用的流操作(重点)
forEach:遍历
count:统计个数
filter:过滤
limit:获取前n个
skip:跳过前n个
map:映射,把一种数据类型转换为另外一种数据类型
concat:组合 把两个流组合为一个流
- 能够将流中的内容收集到集合和数组中(重点)
List<String> list = stream.collect(Collectors.toList());
Set<String> set = stream.collect(Collectors.toSet());
Object[] arr = stream.toArray();
面向对象思想:
做一件事情,找一个能够解决这个事情的对象,调用对象的方法来完成这件事情
函数式编程思想:
重视的是结果,怎么做事情,不重视完成的过程,找谁来做
package com.itheima.demo01Lambda;
/*
使用Lambda表达式简化多线程匿名内部类(重点)
*/
public class Demo01Lambda {
public static void main(String[] args) {
//使用匿名内部类的方式创建一个线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程,正在执行线程任务!");
}
}).start();
//使用Lambda表达式,简化匿名内部类
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"线程,正在执行线程任务!");
}).start();
}
}
Lambda表达式的语法:
由一些参数,一个箭头,一些代码组成
格式:
(参数列表)->{重写抽象方法的方法体}
Lambda表达式作用:简化函数式接口的匿名内部类
lambda表达式使用前提:必须有接口,接口中有且只能有一个抽象方法(函数式接口)
Lambda表达式是可推导,可省略:能推导出来,Lambda表达式重写的就是接口中唯一的抽象方法
Lambda表达式的基本格式
( )->{ } Runnable接口-->public abstract void run();
一些参数,一个箭头,一些代码
():重写接口中唯一抽象方法的参数列表,没有参数就空着,有多个参数使用逗号隔开
->:传递,可以把参数传递给{ }方法体使用
{ }:重写接口中唯一抽象方法的方法体
Lambda表达式的使用前提:
1.必须有接口
2.接口中只能有且仅有一个抽象方法(函数式接口)
注意:
Lambda表达式是可推导可省略
Lambda表达式的目的就是重写接口中唯一的抽象方法
接口的方法只有一个,可以推导出重写的就是接口中唯一的抽象方法,所以可以简化代码
需求:
创建一个数组,数组的类型使用Person
创建3个Person对象,存储到数组中
使用Arrays数组工具类中的方法sort,根据比较器产生的规则对Person对象进行排序(年龄升序)
package com.itheima.demo01Lambda;
import java.util.Arrays;
import java.util.Comparator;
/*
使用Lambda表达式重写有参数有返回值的方法(重点)
需求:
创建一个数组,数组的类型使用Person
创建3个Person对象,存储到数组中
使用Arrays数组工具类中的方法sort,根据比较器产生的规则对Person对象进行排序(年龄升序)
java.util.Arrays:数组工具类
static void sort(T[] a, Comparator super T> c)
根据指定比较器产生的顺序对指定对象数组进行排序。
*/
public class Demo02Lambda {
public static void main(String[] args) {
//创建一个数组,数组的类型使用Person
Person[] arr = new Person[3];
//创建3个Person对象,存储到数组中
arr[0] = new Person("关羽",28);
arr[1] = new Person("刘备",38);
arr[2] = new Person("张飞",18);
//使用Arrays数组工具类中的方法sort,根据比较器产生的规则对Person对象进行排序(年龄升序)
Arrays.sort(arr, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
//排序的规则 o1-o2:升序 o2-o1:降序
return o1.getAge()-o2.getAge();
}
});
//遍历数组
for (Person p : arr) {
System.out.println(p);
}
//使用Lambda表达式,简化Comparator接口的匿名内部类
Arrays.sort(arr,(Person o1,Person o2)->{
//根据年龄降序排序
return o2.getAge()-o1.getAge();
});
System.out.println("---------------------------------------");
//遍历数组
for (Person p : arr) {
System.out.println(p);
}
}
}
package com.itheima.demo01Lambda;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Lambda表达式使用前提:有接口,接口中有且仅有一个抽象方法(函数式接口)
Lambda表达式是可推导,可以省略的
可以推导出,Lambda表达式重写的就是接口中唯一的抽象方法
也可以推导出方法的参数和方法有没有返回值,可以可以对参数和返回值在进行简化
格式:
(参数列表)->{重写抽象方法的方法体}
简化:
1.(参数列表):参数列表的数据类型是可以推导出来的,可以省略
(int a)-->(a)
(int a,String s)-->(a,s)
2.(参数列表):参数列表中只有一个参数,()小括号也可以省略,但是参数列表没有参数,()小括号不能省略
(int a)-->(a)-->a
(int a,String s)-->a,s 错误,两个或者两个以上的参数不能省略()
()-->不能省略-->()
3.{重写抽象方法的方法体}:重写的方法体,如果只有一行代码(java中行是以分号隔开的)
无论方法是否有返回值
{ }和一行代码结束的分号(;)和return关键字可以省略不写
但是他们必须一起省略
package com.itheima.demo01Lambda;
import java.util.Arrays;
/*
Lambda表达式简化格式
*/
public class Demo03Lambda {
public static void main(String[] args) {
//实现多线程的Lambda表达式
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"线程正在执行线程任务!");
System.out.println(Thread.currentThread().getName()+"线程正在执行线程任务!");
System.out.println(Thread.currentThread().getName()+"线程正在执行线程任务!");
System.out.println(Thread.currentThread().getName()+"线程正在执行线程任务!");
}).start();
//简化lambda表达式 参数列表:只有一个()不能省略 方法体:省略的{ }和;
new Thread(()->System.out.println(Thread.currentThread().getName()+"线程正在执行线程任务!")).start();
//创建一个数组,数组的类型使用Person
Person[] arr = new Person[3];
//创建3个Person对象,存储到数组中
arr[0] = new Person("关羽",28);
arr[1] = new Person("刘备",38);
arr[2] = new Person("张飞",18);
//使用Arrays数组工具类中的方法sort,根据比较器产生的规则对Person对象进行排序(年龄升序)
Arrays.sort(arr,(Person o1,Person o2)->{
return o1.getAge()-o2.getAge();
});
//简化Lambda表达式 参数:省略数据类型 方法体:{ } return ;
Arrays.sort(arr,(o1,o2)-> o1.getAge()-o2.getAge());
}
}
我们可以把集合|数组,转换为Stream流,使用Stream流中的方法,对集合|数组进行操作
需求:
List list= new ArrayList<>();
Collections.addAll(list,“张无忌”,“周芷若”,“赵敏”,“张三丰”,“张翠山”,“灭绝师太”,“张三”);
1.首先晒选出所有姓张的人,把姓张的人存储到一个新的集合中
2.筛选名字中是3个字的人,把名字是3个字的人存储到一个新的集合中
3.对最后得到的集合进行遍历
package com.itheima.demo02Stream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/*
不使用Stream流,使用集合遍历的方式完成需求
*/
public class Demo01List {
public static void main(String[] args) {
List<String> list= new ArrayList<>();
Collections.addAll(list,"张无忌","三张","周芷若","赵敏","张三丰","张翠山","灭绝师太","张三");
//1.首先晒选出所有姓张的人,把姓张的人存储到一个新的集合中
List<String> zhangList= new ArrayList<>();
for (String s : list) {
if(s.startsWith("张")){
zhangList.add(s);
}
}
System.out.println(zhangList);//[张无忌, 张三丰, 张翠山, 张三]
//2.筛选名字中是3个字的人,把名字是3个字的人存储到一个新的集合中
List<String> sanList= new ArrayList<>();
for (String s : zhangList) {
if(s.length()==3){
sanList.add(s);
}
}
//3.对最后得到的集合进行遍历
for (String s : sanList) {
System.out.println(s);
}
}
}
package com.itheima.demo02Stream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/*
使用Stream流完成需求
Stream流可以使我们的代码更加优雅==>简化
*/
public class Demo02Stream {
public static void main(String[] args) {
List<String> list= new ArrayList<>();
Collections.addAll(list,"张无忌","三张","周芷若","赵敏","张三丰","张翠山","灭绝师太","张三");
//1.首先晒选出所有姓张的人,把姓张的人存储到一个新的集合中
//2.筛选名字中是3个字的人,把名字是3个字的人存储到一个新的集合中
//3.对最后得到的集合进行遍历
//把集合转换为Stream流,使用Stream流中的方法操作
list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length()==3).forEach(s -> System.out.println(s));
}
}
流式思想:流水线
package com.itheima.demo02Stream;
import java.util.*;
import java.util.stream.Stream;
/*
获取Stream流的方式(重点)
1.在JDK1.8版本之后,Collection接口中,定义了一个方法叫stream,用于把集合转换为Stream流对象
default Stream stream() 返回以此集合作为源的顺序 Stream 。
Collection接口下的所有的集合(ArrayList,LinkedList,HashSet)都可以使用此方法,获取Stream流
注意:Map集合不能转换为Stream流的
2.在JDK1.8版本之后,增加一个接口名字Stream,在接口中有一个静态方法叫of,用于把可变参数(数组)转换为Stream流
java.util.stream.Stream接口
静态方法:
static Stream of(T... values) 方法的参数可以传递可变参数,也可以传递数组
可变参数的底层就是一个数组,使用数组来接收传递的不同个数的参数
可变参数作用:可以接收任意同种数据类型的参数(0个,1个,2个...10000个...)
*/
public class Demo03Stream {
public static void main(String[] args) {
show02();
}
/*
使用静态of方法,把可变参数(数组),转换为Stream流
*/
private static void show02() {
Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> stream2 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
Stream<String> stream3 = Stream.of("你好", "我好", "大家好", "才是真的好");
//可变参数底层采用的数组,所以可以传递可变参数方法,都可以传递数组
String[] arr1 = {"你好", "我好", "大家好", "才是真的好"};
Stream<String> stream4 = Stream.of(arr1);
//可变参数的数组类型必须是包装类
int[] arr2 = {1,2,3,4,5};
//把arr2这个数组,作为一个元素转换为Stream流
Stream<int[]> stream5 = Stream.of(arr2);
System.out.println(stream5.count());//1 统计个数
Integer[] arr3 = {1,2,3,4,5};
Stream<Integer> stream6 = Stream.of(arr3);
System.out.println(stream6.count());//5 统计个数
}
/*
把Collection接口下的集合转换为Stream流
注意:
Stream流是有泛型的,泛型跟着集合走
*/
private static void show01() {
ArrayList<String> list = new ArrayList<>();
//把ArrayList集合转换为Stream流
Stream<String> stream1 = list.stream();
LinkedList<Integer> linked = new LinkedList<>();
//把LinkedList集合转换为Stream流
Stream<Integer> stream2 = linked.stream();
HashSet<Double> set = new HashSet<>();
//把HashSet集合转换为Stream流
Stream<Double> stream3 = set.stream();
HashMap<String,Integer> map = new HashMap<>();
//注意:Map集合不能转换为Stream流的
//map.stream();//Cannot resolve method 'stream()'
Set<String> keySet = map.keySet();
//可以把Map集合中所有的key转换为Stream流
Stream<String> stream4 = keySet.stream();
Collection<Integer> values = map.values();
//可以把Map集合中所有的value转换为Stream流
Stream<Integer> stream5 = values.stream();
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
//可以把Map集合中所有的entry对象转换为Stream流
Stream<Map.Entry<String, Integer>> stream6 = entrySet.stream();
}
}
流模型的操作很丰富,这里介绍一些常用的API。这些方法可以被分成两种:
Stream
接口自身类型的方法,因此不再支持类似StringBuilder
那样的链式调用。本小节中,终结方法包括count
和forEach
方法。Stream
接口自身类型的方法,因此支持链式调用。(除了终结方法外,其余方法均为非终结方法。)在上述介绍的各种方法中,凡是返回值仍然为Stream
接口的为函数拼接方法,它们支持链式调用;而返回值不再为Stream
接口的为终结方法,不再支持链式调用。如下表所示:
方法名 | 方法作用 | 方法种类 | 是否支持链式调用 |
---|---|---|---|
count | 统计个数 | 终结 | 否 |
forEach | 逐一处理 | 终结 | 否 |
filter | 过滤 | 函数拼接 | 是 |
limit | 取用前几个 | 函数拼接 | 是 |
skip | 跳过前几个 | 函数拼接 | 是 |
map | 映射 | 函数拼接 | 是 |
concat | 组合 | 函数拼接 | 是 |
备注:本小节之外的更多方法,请自行参考API文档。
package com.itheima.demo03StreamMethod;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;
/*
Stream流中的常用方法_forEach:用于遍历Stream流中的元素
void forEach(Consumer super T> action) 对此流的每个元素执行操作。
参数:
Consumer super T> action:是一个消费型的接口,参数可以传递Lambda表达式
唯一的抽象方法:
void accept(T t) :消费一个指定泛型类型的数据
注意:
forEach方法是一个终结方法,没有返回值;也不能使用链式编程调用Stream流中的其他方法了
*/
public class Demo01forEach {
public static void main(String[] args) {
List<String> list= new ArrayList<>();
Collections.addAll(list,"张无忌","三张","周芷若","赵敏","张三丰","张翠山","灭绝师太","张三");
//把List集合转换为Stream流
Stream<String> stream = list.stream();
//forEach方法参数传递的是Consumer接口的匿名内部类对象
/*stream.forEach(new Consumer() {
@Override
public void accept(String s) {
System.out.println(s);
}
});*/
//Consumer接口是一个函数式接口,所以可以使用Lambda表达式,简化Consumer接口匿名内部类
/*
IllegalStateException: stream has already been operated upon or closed
抛出非法状态异常:Stream流对象只能使用一次,使用完毕就会被销毁了,就不能在使用了
*/
/*stream.forEach((String s)->{
System.out.println(s);
});*/
//简化Stream流对象
stream.forEach(s -> System.out.println(s));
}
}
package com.itheima.demo03StreamMethod;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
/*
Stream流中的常用方法_count方法:统计个数
long count() 返回此流中的元素数。
注意:
count方法是一个终结方法,返回值类型是long类型;也不能使用链式编程调用Stream流中的其他方法了
*/
public class Demo02count {
public static void main(String[] args) {
//使用Stream接口中的静态方法of获取Stream流对象
Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
long c1 = stream1.count();
System.out.println("c1:"+c1);//c1:9
List<String> list= new ArrayList<>();
Collections.addAll(list,"张无忌","三张","周芷若","赵敏","张三丰","张翠山","灭绝师太","张三");
Stream<String> stream2 = list.stream();
long c2 = stream2.count();
System.out.println("c2:"+c2);//c2:8
}
}
package com.itheima.demo03StreamMethod;
import java.util.function.Predicate;
import java.util.stream.Stream;
/*
Stream流中的常用方法_filter方法:用于过滤Stream流中的元素
Stream filter(Predicate super T> predicate)
参数:
Predicate super T> predicate:函数式接口,参数传递lambda表达式
唯一的抽象方法:
boolean test(T t) 用于对接口指定泛型类型的数据进行判断
注意:
filter方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
*/
public class Demo03filter {
public static void main(String[] args) {
//获取Stream流对象
Stream<String> stream = Stream.of("美羊羊", "喜羊羊", "沸羊羊", "慢羊羊", "暖羊羊", "懒羊羊", "灰太狼", "红太狼", "小灰灰");
//需求:对stream中的元素进行过滤,只要包含"羊羊"的元素,存储到一个新的Stream流中
/*Stream stream2 = stream.filter(new Predicate() {
@Override
public boolean test(String s) {
//返回true:满足条件,把元素添加到新的流中 返回false:不满足条件,把元素过滤掉
return s.contains("羊羊");
}
});*/
//使用Lambda表达式简化Predicate接口的匿名内部类
/*Stream stream2 = stream.filter((String s) -> {
return s.contains("羊羊");
});*/
//简化Lambda表达式
//Stream stream2 = stream.filter(s->s.contains("羊羊"));
//System.out.println(stream2.count());//6
//对stream2流对象进行遍历
//stream2.forEach(s -> System.out.println(s));
//链式编程
stream.filter(s->s.contains("羊羊")).forEach(s -> System.out.println(s));
}
}
package com.itheima.demo03StreamMethod;
import java.util.stream.Stream;
/*
Stream流中的常用方法_limit方法:获取前n个元素
Stream limit(long maxSize) 返回由此流的元素组成的流,截短长度不能超过 maxSize 。
例如:
limit(4);获取流中的前4个元素,把前4个元素存储到一个新的Steam流中
注意:
1.传递数字大于流的长度,返回流中所有的元素
2.limit方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
*/
public class Demo04limit {
public static void main(String[] args) {
Stream<String> stream = Stream.of("美羊羊", "喜羊羊", "沸羊羊", "慢羊羊", "暖羊羊", "懒羊羊", "灰太狼", "红太狼", "小灰灰");
//把stream流中的前6个元素,存储到一个新的Stream流中返回
//Stream stream2 = stream.limit(6);
//遍历stream2流对象
//stream2.forEach(s -> System.out.println(s));
//链式编程
stream.limit(6).forEach(s -> System.out.println(s));
}
}
package com.itheima.demo03StreamMethod;
import java.util.stream.Stream;
/*
Stream流中的常用方法_skip方法:跳过前n个元素
Stream skip(long n)
skip(3)==> 跳过前3个元素,把剩余的元素存储到一个新的Stream流中
注意:
1.skip跳过的元素数量大于流中的个数,返回一个没有元素的空流
2.skip方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
*/
public class Demo05skip {
public static void main(String[] args) {
Stream<String> stream = Stream.of("美羊羊", "喜羊羊", "沸羊羊", "慢羊羊", "暖羊羊", "懒羊羊", "灰太狼", "红太狼", "小灰灰");
//需求:使用skip方法跳过(6)元素,把剩余的三个狼存储到一个新的Stream流中
//Stream stream2 = stream.skip(6);
//遍历stream2流对象
//System.out.println(stream2.count());//3
//stream2.forEach(s -> System.out.println(s));
//链式编程
stream.skip(6).forEach(s -> System.out.println(s));
}
}
package com.itheima.demo03StreamMethod;
import java.util.function.Function;
import java.util.stream.Stream;
/*
Stream流中的常用方法_map方法:映射,类型转换
Stream map(Function mapper)
参数:
Function mapper:函数式接口,可以传递Lambda表达式
接口中唯一的抽象方法:
R apply(T t) 根据参数类型T获取类型R类型的返回值,用于类型转换 T转换R
注意:
map方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
*/
public class Demo06map {
public static void main(String[] args) {
//创建一个String类型的Stream流
Stream<String> stream1 = Stream.of("11", "22", "33");
//使用map方法,把String类型的Stream,转换为Integer类型的Stream流
/*Stream stream2 = stream1.map(new Function() {
@Override
public Integer apply(String s) {
//把字符串类型参数,转换为Integer类型返回
return Integer.parseInt(s);
}
});*/
//使用Lambda表达式简化函数式接口Function的匿名内部类
/* Stream stream2 = stream1.map((String s) -> {
return Integer.parseInt(s);
});*/
//简化Lambda表达式
//Stream stream2 = stream1.map(s -> Integer.parseInt(s));
//遍历stream2流对象
//stream2.forEach(s-> System.out.println(s+10));//21,32,43
//链式编程
stream1.map(s -> Integer.parseInt(s)).forEach(s-> System.out.println(s+10));
//创建一个String类型的Stream流
Stream<String> stream3 = Stream.of("迪丽热巴", "古力娜扎", "佟丽娅");
//把String类型的Stream流,转换为Person类型的Stream流
//Stream stream4 = stream3.map(s -> new Person(s));
//遍历stream4流对象
//stream4.forEach(p-> System.out.println(p));
//链式编程
stream3.map(s -> new Person(s)).forEach(p-> System.out.println(p));
}
}
package com.itheima.demo03StreamMethod;
public class Person {
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.itheima.demo03StreamMethod;
import java.util.stream.Stream;
/*
Stream流中的常用方法_concat方法:组合,把两个Stream流,组合为一个新的Stream流
static Stream concat(Stream extends T> a, Stream extends T> b)
注意:
concat方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
*/
public class Demo07concat {
public static void main(String[] args) {
Stream<String> stream1 = Stream.of("美羊羊", "喜羊羊", "沸羊羊", "慢羊羊", "暖羊羊", "懒羊羊");
Stream<String> stream2 = Stream.of("迪丽热巴", "古力娜扎", "佟丽娅");
//使用Stream接口中的静态方法concat,把以上两个流对象组合为一个新的流对象
//Stream stream = Stream.concat(stream1, stream2);
//遍历stream流对象
//stream.forEach(s -> System.out.println(s));
//链式编程
Stream.concat(stream1,stream2).forEach(s -> System.out.println(s));
}
}
现在有两个 ArrayList 集合存储队伍当中的多个成员姓名,要求使用传统的for循环(或增强for循环)
依次进行以下若干操作步骤:
1. 第一个队伍只要名字为3个字的成员姓名,把3个字成员的姓名存储到一个新的集合中
2. 第一个队伍筛选之后只要前3个人,把前3个人存储到一个新的集合中
3. 第二个队伍只要姓张的成员姓名,把姓张的成员姓名存储到一个新的集合中
4. 第二个队伍筛选之后不要前2个人,跳过前2个人,把其余的人存储到一个新的集合中
5. 将两个队伍合并为一个队伍,把两个过滤之后集合组合为一个新的集合
6. 根据姓名创建 Person 对象,把Person对象存储到一个新的集合
7. 打印整个队伍的Person对象信息。
List<String> one = new ArrayList<>();
one.add("迪丽热巴");
one.add("宋远桥");
one.add("苏星河");
one.add("老子");
one.add("庄子");
one.add("孙子");
one.add("洪七公");
one.add("张无忌");
one.add("周伯通");
List<String> two = new ArrayList<>();
two.add("古力娜扎");
two.add("张无忌");
two.add("张三丰");
two.add("赵丽颖");
two.add("张二狗");
two.add("张天爱");
two.add("张三");
package com.itheima.demo04StreamTest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/*
现在有两个 ArrayList 集合存储队伍当中的多个成员姓名,要求使用传统的for循环(或增强for循环)
依次进行以下若干操作步骤:
1. 第一个队伍只要名字为3个字的成员姓名,把3个字成员的姓名存储到一个新的集合中
2. 第一个队伍筛选之后只要前3个人,把前3个人存储到一个新的集合中
3. 第二个队伍只要姓张的成员姓名,把姓张的成员姓名存储到一个新的集合中
4. 第二个队伍筛选之后不要前2个人,跳过前2个人,把其余的人存储到一个新的集合中
5. 将两个队伍合并为一个队伍,把两个过滤之后集合组合为一个新的集合
6. 根据姓名创建 Person 对象,把Person对象存储到一个新的集合
7. 打印整个队伍的Person对象信息。
*/
public class Demo01List {
public static void main(String[] args) {
List<String> one = new ArrayList<>();
one.add("迪丽热巴");
one.add("宋远桥");
one.add("苏星河");
one.add("老子");
one.add("庄子");
one.add("孙子");
one.add("洪七公");
one.add("张无忌");
one.add("周伯通");
//1. 第一个队伍只要名字为3个字的成员姓名,把3个字成员的姓名存储到一个新的集合中
List<String> one1 = new ArrayList<>();
for (String s : one) {
if(s.length()==3){
one1.add(s);
}
}
System.out.println(one1);//[宋远桥, 苏星河, 洪七公, 张无忌, 周伯通]
//2. 第一个队伍筛选之后只要前3个人,把前3个人存储到一个新的集合中
List<String> one2 = new ArrayList<>();
for (int i = 0; i < 3; i++) {//i=0,1,2
one2.add(one1.get(i));
}
System.out.println(one2);//[宋远桥, 苏星河, 洪七公]
List<String> two = new ArrayList<>();
two.add("古力娜扎");
two.add("张无忌");
two.add("张三丰");
two.add("赵丽颖");
two.add("张二狗");
two.add("张天爱");
two.add("张三");
//3. 第二个队伍只要姓张的成员姓名,把姓张的成员姓名存储到一个新的集合中
List<String> two1 = new ArrayList<>();
for (String s : two) {
if(s.startsWith("张")){
two1.add(s);
}
}
System.out.println(two1);//[张无忌, 张三丰, 张二狗, 张天爱, 张三]
//4. 第二个队伍筛选之后不要前2个人,跳过前2个人,把其余的人存储到一个新的集合中
List<String> two2 = new ArrayList<>();
for (int i = 2; i < two1.size(); i++) {
two2.add(two1.get(i));
}
System.out.println(two2);//[张二狗, 张天爱, 张三]
//5. 将两个队伍合并为一个队伍,把两个过滤之后集合组合为一个新的集合
//[宋远桥, 苏星河, 洪七公] [张二狗, 张天爱, 张三]
List<String> all = new ArrayList<>();
/*for (String s : one2) {
all.add(s);
}
for (String s : two2) {
all.add(s);
}*/
/*
java.util.Collection接口
boolean addAll(Collection extends E> c) 将指定集合中的所有元素添加到此集合
*/
all.addAll(one2);
all.addAll(two2);
System.out.println(all);//[宋远桥, 苏星河, 洪七公, 张二狗, 张天爱, 张三]
//6. 根据姓名创建 Person 对象,把Person对象存储到一个新的集合
List<Person> list = new ArrayList<>();
for (String s : all) {
list.add(new Person(s));
}
//7. 打印整个队伍的Person对象信息。
for (Person p : list) {
System.out.println(p);
}
}
}
package com.itheima.demo04StreamTest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
/*
现在有两个 ArrayList 集合存储队伍当中的多个成员姓名,要求使用Stream流的方式
依次进行以下若干操作步骤:
1. 第一个队伍只要名字为3个字的成员姓名,把3个字成员的姓名存储到一个新的集合中
2. 第一个队伍筛选之后只要前3个人,把前3个人存储到一个新的集合中
3. 第二个队伍只要姓张的成员姓名,把姓张的成员姓名存储到一个新的集合中
4. 第二个队伍筛选之后不要前2个人,跳过前2个人,把其余的人存储到一个新的集合中
5. 将两个队伍合并为一个队伍,把两个过滤之后集合组合为一个新的集合
6. 根据姓名创建 Person 对象,把Person对象存储到一个新的集合
7. 打印整个队伍的Person对象信息。
*/
public class Demo02Stream {
public static void main(String[] args) {
List<String> one = new ArrayList<>();
one.add("迪丽热巴");
one.add("宋远桥");
one.add("苏星河");
one.add("老子");
one.add("庄子");
one.add("孙子");
one.add("洪七公");
one.add("张无忌");
one.add("周伯通");
//1. 第一个队伍只要名字为3个字的成员姓名,把3个字成员的姓名存储到一个新的集合中
//2. 第一个队伍筛选之后只要前3个人,把前3个人存储到一个新的集合中
//把集合转换为Stream流
Stream<String> oneStream = one.stream().filter(s -> s.length() == 3).limit(3);
List<String> two = new ArrayList<>();
two.add("古力娜扎");
two.add("张无忌");
two.add("张三丰");
two.add("赵丽颖");
two.add("张二狗");
two.add("张天爱");
two.add("张三");
//3. 第二个队伍只要姓张的成员姓名,把姓张的成员姓名存储到一个新的集合中
//4. 第二个队伍筛选之后不要前2个人,跳过前2个人,把其余的人存储到一个新的集合中
//把集合转换为Stream流
Stream<String> twoStream = two.stream().filter(s -> s.startsWith("张")).skip(2);
//5. 将两个队伍合并为一个队伍,把两个过滤之后集合组合为一个新的集合
//6. 根据姓名创建 Person 对象,把Person对象存储到一个新的集合
//7. 打印整个队伍的Person对象信息。
Stream.concat(oneStream,twoStream).map(s -> new Person(s)).forEach(p-> System.out.println(p));
/*Stream.concat(
one.stream().filter(s -> s.length() == 3).limit(3),
two.stream().filter(s -> s.startsWith("张")).skip(2))
.map(s -> new Person(s)).forEach(p-> System.out.println(p));*/
}
}
把Stream流转换为集合或者把Stream流转换为数组
package com.itheima.demo05Stream;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/*
把Stream流转换为集合:收集到集合中
可以使用Stream流中的方法collect把Stream转换为集合
R collect(Collector super T,A,R> collector)
参数:
Collector是一个接口,需要传递接口的实现类对象
java.util.stream.Collectors:操作Collector的工具类
static Collector> toList() 返回Collector接口的实现类对象,可以把Stream流转换为List集合
static Collector> toSet() 返回Collector接口的实现类对象,可以把Stream流转换为Set集合
*/
public class Demo01StreamToCollection {
public static void main(String[] args) {
Stream<String> stream = Stream.of("美羊羊", "喜羊羊", "沸羊羊", "慢羊羊", "暖羊羊", "懒羊羊","美羊羊");
//把stream流对象转换为List:收集到List集合中==>1.有序 2.允许重复 3.包含带索引的方法
//List list = stream.collect(Collectors.toList());
//System.out.println(list);//[美羊羊, 喜羊羊, 沸羊羊, 慢羊羊, 暖羊羊, 懒羊羊, 美羊羊]
//把stream流对象转换为Set:收集到Set集合中==>1.不允许存储重复元素 2.不包含带索引的方法
Set<String> set = stream.collect(Collectors.toSet());
System.out.println(set);//[美羊羊, 沸羊羊, 暖羊羊, 喜羊羊, 懒羊羊, 慢羊羊]
System.out.println(set.getClass());//class java.util.HashSet
}
}
package com.itheima.demo05Stream;
import java.util.stream.Stream;
/*
将流中的元素收集到数组(将流转成数组)
Stream接口中的方法
Object[] toArray() 把Stream流转换为数组
*/
public class Demo02StreamToArray {
public static void main(String[] args) {
Stream<String> stream = Stream.of("美羊羊", "喜羊羊", "沸羊羊", "慢羊羊", "暖羊羊", "懒羊羊","美羊羊");
Object[] arr = stream.toArray();
for (Object o : arr) {
System.out.println(o);
}
}
}