两种获取Stream流的方式
Demo01GetStream
package cn.xiaoge.day21.demo02;
/*
java.util.stream.Stream是Java1.8新加入的最常用的流接口. (这并不是一个函数式接口)
获取一个流非常简单, 有以下几种常用的方式:
所有的Collection集合都可以通过stream默认方法获取流;
default Stream stream() 返回一个序列 Stream与此集合作为其来源。
Stream接口的静态方法of可以获取数组对应的流.
static Stream of(T... values) 返回其元素是指定值的顺序排序流。
参数是一个可变参数, 那么我们就可以传递一个数组
*/
import java.util.*;
import java.util.stream.Stream;
public class Demo01GetStream {
public static void main(String[] args) {
// 把集合转换为Stream
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
Set<String> set = new HashSet<>();
Stream<String> stream2 = set.stream();
Map<String, String> map = new HashMap<>();
// 获取键, 存到Set集合中
Set<String> keySet = map.keySet();
Stream<String> stream3 = keySet.stream();
// 获取值, 存到一个Collection集合中
Collection<String> values = map.values();
Stream<String> stream4 = values.stream();
Set<Map.Entry<String, String>> entries = map.entrySet();
Stream<Map.Entry<String, String>> stream5 = entries.stream();
// 把数组转换为Stream流
Stream<Integer> stream6 = Stream.of(1, 2, 3, 4, 5);
// 可变参数可以传递数组
Integer[] arr = {1, 2, 3, 4, 5};
Stream<Integer> stream7 = Stream.of(arr);
String[] arr1 = {"1", "2", "3", "4", "5"};
Stream<String> stream8 = Stream.of(arr1);
}
}
Stream流中的常用方法_forEach
Demo02Stream_forEach
package cn.xiaoge.day21.demo02;
/*
Stream流中的常用方法_forEach
void forEach(Consumer action);
该方法接受一个Consumer接口函数, 会将每一个流元素交给该函数进行处理
Consumer接口是一个消费型的函数式接口, 可以传递Lambda表达式, 消费数据
简单计:
forEach方法, 用来遍历流中的数据
是一个终结方法, 遍历之后就不能继续调用Stream中的其他方法
*/
import java.util.stream.Stream;
public class Demo02Stream_forEach {
public static void main(String[] args) {
// 获取一个Stream流
Stream<String> stream = Stream.of("张三", "李四", "王五", "赵六", "田七");
// 使用Stream流中的方法forEach对Stream流中的数据继续你行遍历
/*
stream.forEach((String name) -> {
System.out.println(name);
});
*/
// 优化Lambda表达式, 这里必须注释上面才能使用下面的这个, 因为forEach是终结方法
stream.forEach(name-> System.out.println(name));
}
}
// 运行结果
张三
李四
王五
赵六
田七
Stream流中的常用方法_filter
Demo03Stream_filter
package cn.xiaoge.day21.demo02;
/*
Stream流中的常用方法_forEach
void forEach(Consumer action);
filter方法的参数Predicate是一个函数式接口, 所以可以传递Lambda表达式, 对数据进行过滤
Predicate中的抽象方法:
boolean test(T t);
*/
import java.util.stream.Stream;
public class Demo03Stream_filter {
public static void main(String[] args) {
// 创建一个Stream流
Stream<String> stream = Stream.of("张无忌", "周芷若", "赵敏", "张强", "张三丰");
// 对Stream流中的元素进行过滤, 只要行张的人
/*Stream stream2 = stream.filter((String name)->{
return name.startsWith("张");
});*/
// 优化Lambda表达式
Stream<String> stream2 = stream.filter(name->name.startsWith("张"));
// 遍历stream2流
stream2.forEach(name-> System.out.println(name));
/*
Stream流属于管道流, 只能消费(使用)一次
第一个Stream流调用完毕方法, 数据就会流转到下一个Stream上
而这时第一个Stream流已经使用完毕, 就会关闭
所以第一个Stream流就不能再调用方法了
*/
// 遍历stream流 报错
// stream.forEach(name-> System.out.println(name)); // java.lang.IllegalStateException
}
}
// 运行结果
张无忌
张强
张三丰
Stream流中的常用方法_map
Demo04Stream_map
package cn.xiaoge.day21.demo02;
/*
如果需要将流中的元素映射到另一个流中,可以使用 map 方法。
Stream map(Function mapper);
该接口需要一个 Function 函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型的流。
Function中的抽象方法:
R apply(T t);
*/
import java.util.function.Function;
import java.util.stream.Stream;
public class Demo04Stream_map {
public static void main(String[] args) {
// 获取一个Stream类型的Stream流
Stream<String> stream = Stream.of("1", "2", "3", "4", "5");
// 使用map方法, 把字符串类型的整数, 转换(映射)为Integer类型的整数
Stream<Integer> stream1 = stream.map(number -> Integer.parseInt(number));
// 遍历stream1流
stream1.forEach(number-> System.out.println(number.getClass() + " " + number));
}
}
// 运行结果
class java.lang.Integer 1
class java.lang.Integer 2
class java.lang.Integer 3
class java.lang.Integer 4
class java.lang.Integer 5
Stream流中的常用方法_count
Demo05Stream_count
package cn.xiaoge.day21.demo02;
/*
Stream流中的常用方法_count: 用于统计Stream流中的元素的个数
long count();
count方法是一个终结方法, 返回值是一个long类型的整数
所以不能继续调用Stream流中的其他方法了
*/
import java.util.ArrayList;
public class Demo05Stream_count {
public static void main(String[] args) {
// 获取一个Stream流
ArrayList<Integer> list = new ArrayList<>();
// 添加元素
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
long count = list.stream().count();
System.out.println(count);
}
}
// 运行结果
5
Stream流中的常用方法_limit
Demo06Stream_limit
package cn.xiaoge.day21.demo02;
/*
Stream流中的常用方法_limit: 用于截取流中的元素
limit方法可以对流进行截取, 只取用前n个
Stream limit(long maxSize);
参数是一个long型, 如果集合当前长度大于参数则进行截取; 否则不进行操作
limit方法是一个延迟方法, 只是对流中的元素进行截取, 返回的是一个新的流, 所以可以继续调用Stream流中的其他方法
*/
import java.util.stream.Stream;
public class Demo06Stream_limit {
public static void main(String[] args) {
// 获取一个Stream流
String[] arr = {"喜洋洋", "美羊羊", "懒洋洋", "灰太狼", "红太狼"};
Stream<String> stream = Stream.of(arr);
// limit(4)截取前四个元素, 返回新的流, 然后对新的流进行forEach遍历
stream.limit(4).forEach(name-> System.out.println(name));
}
}
// 运行结果
喜洋洋
美羊羊
懒洋洋
灰太狼
Stream流中的常用方法_skip
Demo07Stream_skip
package cn.xiaoge.day21.demo02;
/*
Stream流中的常用方法_skip;用于跳过元素
如果希望跳过前几个元素, 可以使用skip方法获取一个截取之后的新流;
Stream skip(long n);
如果流的当前长度大于n, 则跳过前n个; 否则将会得到一个长度为0的空流
*/
import java.util.stream.Stream;
public class Demo07Stream_skip {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
// 使用skip跳过3个元素
// Stream stream2 = stream.skip(3); // 这里的3是3个元素, 不是下标
// stream2.forEach(number-> System.out.println(number)); // 4 5
stream.skip(6).forEach(number-> System.out.println(number)); // 空流
}
}
// 运行结果
空的因为总共就5个元素
Stream流中的常用方法_concat
Demo08Stream_concat
package cn.xiaoge.day21.demo02;
/*
Stream流中的常用方法_concat: 用于把流组合到一起
如果两个流, 希望合并成为一个流, 那么可以使用Stream接口的静态方法concat
static Stream concat(Streama, Stream b)
*/
import java.util.stream.Stream;
public class Demo08Stream_concat {
public static void main(String[] args) {
// 创建一个stream流
Stream<String> stream = Stream.of("张无忌", "周芷若", "赵敏", "张强", "张三丰");
// 创建一个stream2流
Stream<String> stream2 = Stream.of("张三", "李四", "王五", "赵六", "田七");
// concat把两个流合并成一个流
Stream<String> stream3 = Stream.concat(stream, stream2);
stream3.forEach(name-> System.out.println(name));
}
}
// 运行结果
张无忌
周芷若
赵敏
张强
张三丰
张三
李四
王五
赵六
田七
集合元素的处理—传统方式&Stream方式
Person
package cn.xiaoge.day21.demo03;
public class Person {
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
Demo01StreamTest
package cn.xiaoge.day21.demo03;
/*
练习: 集合元素处理(传统方式)
现在有两个 ArrayList 集合存储队伍当中的多个成员姓名,要求使用传统的for循环(或增强for循环)依次进行以 下若干操作步骤:
1. 第一个队伍只要名字为3个字的成员姓名;存储到一个新集合中。
2. 第一个队伍筛选之后只要前3个人;存储到一个新集合中。
3. 第二个队伍只要姓张的成员姓名;存储到一个新集合中。
4. 第二个队伍筛选之后不要前2个人;存储到一个新集合中。
5. 将两个队伍合并为一个队伍;存储到一个新集合中。
6. 根据姓名创建 Person 对象;存储到一个新集合中。
7. 打印整个队伍的Person对象信息。
*/
import java.util.ArrayList;
public class Demo01StreamTest {
public static void main(String[] args) {
// 现在有两个 ArrayList 集合存储队伍当中的多个成员姓名,要求使用传统的for循环(或增强for循环)依次进行以 下若干操作步骤:
ArrayList<String> one = new ArrayList<>();
one.add("迪丽热巴");
one.add("宋远桥");
one.add("苏星河");
one.add("石破天");
one.add("石中玉");
one.add("老子");
one.add("庄子");
one.add("洪七公");
ArrayList<String> two = new ArrayList<>();
two.add("古力娜扎");
two.add("张无忌");
two.add("赵丽颖");
two.add("张三丰");
two.add("尼古拉斯赵四");
two.add("张天爱");
two.add("张二狗");
// 1. 第一个队伍只要名字为3个字的成员姓名;存储到一个新集合中。
ArrayList<String> three = new ArrayList<>();
for (String s : one) {
if(s.length() == 3){
three.add(s);
}
}
for (String s : two) {
if(s.length() == 3){
three.add(s);
}
}
// 2. 第一个队伍筛选之后只要前3个人;存储到一个新集合中。
ArrayList<String> four = new ArrayList<>();
for (int i = 0; i < three.size(); i++) {
if (i < 3) {
four.add(three.get(i));
}
}
// 3. 第二个队伍只要姓张的成员姓名;存储到一个新集合中。
ArrayList<String> five = new ArrayList<>();
for (String s : three) {
if(s.startsWith("张")){
five.add(s);
}
}
// 4. 第二个队伍筛选之后不要前2个人;存储到一个新集合中。
ArrayList<String> six = new ArrayList<>();
for (int i = 0; i < five.size(); i++) {
if(i < 2){
continue;
}
six.add(five.get(i));
}
// 5. 将两个队伍合并为一个队伍;存储到一个新集合中。
ArrayList<String> seven = new ArrayList<>();
for (String s : four) {
seven.add(s);
}
for (String s : six) {
seven.add(s);
}
// 6. 根据姓名创建 Person 对象;存储到一个新集合中。
ArrayList<Person> eight = new ArrayList<>();
for (String s : seven) {
Person p = new Person(s);
eight.add(p);
}
// 7. 打印整个队伍的Person对象信息。
for (Person person : eight) {
System.out.println(person);
}
}
}
// 运行结果
Person{name='宋远桥'}
Person{name='苏星河'}
Person{name='石破天'}
Person{name='张天爱'}
Person{name='张二狗'}
Demo02StreamTest
package cn.xiaoge.day21.demo03;
/*
练习: 集合元素处理(传统方式)
现在有两个 ArrayList 集合存储队伍当中的多个成员姓名,要求使用传统的for循环(或增强for循环)依次进行以 下若干操作步骤:
1. 第一个队伍只要名字为3个字的成员姓名;存储到一个新集合中。
2. 第一个队伍筛选之后只要前3个人;存储到一个新集合中。
3. 第二个队伍只要姓张的成员姓名;存储到一个新集合中。
4. 第二个队伍筛选之后不要前2个人;存储到一个新集合中。
5. 将两个队伍合并为一个队伍;存储到一个新集合中。
6. 根据姓名创建 Person 对象;存储到一个新集合中。
7. 打印整个队伍的Person对象信息。
*/
import java.util.ArrayList;
import java.util.stream.Stream;
public class Demo02StreamTest {
public static void main(String[] args) {
// 现在有两个 ArrayList 集合存储队伍当中的多个成员姓名,要求使用传统的for循环(或增强for循环)依次进行以 下若干操作步骤:
ArrayList<String> one = new ArrayList<>();
one.add("迪丽热巴");
one.add("宋远桥");
one.add("苏星河");
one.add("石破天");
one.add("石中玉");
one.add("老子");
one.add("庄子");
one.add("洪七公");
ArrayList<String> two = new ArrayList<>();
two.add("古力娜扎");
two.add("张无忌");
two.add("赵丽颖");
two.add("张三丰");
two.add("尼古拉斯赵四");
two.add("张天爱");
two.add("张二狗");
// 1. 第一个队伍只要名字为3个字的成员姓名;存储到一个新集合中。
// 2. 第一个队伍筛选之后只要前3个人;存储到一个新集合中。
Stream<String> stream1 = Stream.concat(one.stream().filter(name -> name.length() == 3), two.stream().filter(name -> name.length() == 3)).limit(3);
// 3. 第二个队伍只要姓张的成员姓名;存储到一个新集合中。
// 4. 第二个队伍筛选之后不要前2个人;存储到一个新集合中。
Stream<String> stream2 = Stream.concat(one.stream().filter(name->name.startsWith("张")), two.stream().filter(name->name.startsWith("张"))).skip(2);
// 5. 将两个队伍合并为一个队伍;存储到一个新集合中。
Stream<String> stream3 = Stream.concat(stream1, stream2);
// 6. 根据姓名创建 Person 对象;存储到一个新集合中。
// 7. 打印整个队伍的Person对象信息。
stream3.forEach(name-> System.out.println(new Person(name)));
}
}
// 运行结果
Person{name='宋远桥'}
Person{name='苏星河'}
Person{name='石破天'}
Person{name='张天爱'}
Person{name='张二狗'}