package study.stream;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张大哥");
list.add("李三哥");
list.add("张二哥");
list.add("马五弟");
list.add("张六弟");
//需求:找出姓张的哥哥
//传统方法
for (String s : list) {
if(s.startsWith("张")&&s.endsWith("哥")){
System.out.println(s);
}
}
//stream流的方式
list.stream()
.filter((s)->s.startsWith("张"))
.filter((s)->s.endsWith("哥"))
.forEach(System.out::println);
}
}
Stream的作用是使对一些数据的操作更加方便、快捷;
就像工厂里的生产线对产品进行多步骤加工,每一步加工之后返回的还是产品本身,只不过是加工过的产品,然后继续下一步加工操作,就像上面的代码,每一行代码就相当于进行一次加工,加工后还是返回产品本身,所以可以直接进行下一个方法调用;
①元素是特定类型的对象,形成一个队列;(在java中Stream并不会存储数据,只是进行按需计算)
②数据源:流的来源。可以是集合、数组等;
①Pipelining:中间操作都会返回流本身;
②内部迭代:以前对集合的遍历都是通过Iterator迭代器进行的,这种叫外部迭代;Stream提供了内部迭代的方式,流可以直接调用遍历方法;
①获取数据源(Source);
②数据转换;
③执行操作获取想要的结果;
//一、把集合转换为Stream流
//list集合
List<String> list = new ArrayList<>();
Stream<String> s1 = list.stream();
//set集合
Set<String> set = new HashSet<>();
Stream<String> s2 = set.stream();
//map集合
Map<String,String> map = new HashMap<>();
//获取键,存储到一个set集合中
Set<String> set1 = map.keySet();
Stream<String> s3 = set1.stream();
//获取值,存储到一个Collection集合中
Collection<String> collection = map.values();
Stream<String> s4 = collection.stream();
//获取键值对(键与值的映射关系 entrySet)
Set<Map.Entry<String, String>> entrySet = map.entrySet();
Stream<Map.Entry<String, String>> s5 = entrySet.stream();
//二、把数组转换为Stream流
Integer[] arr = {1,2,3,4,5};
Stream<Integer> stream = Stream.of(arr);
String[] strings = {"你好!","Hello!","哈哈哈!"};
Stream<String> stream1 = Stream.of(strings);
返回值类型仍然是Stream接口自身类型的方法,因此支持链式调用(除了终结方法外,其他方法都是延迟方法);
返回值类型不再是Stream接口自身的方法,因此不再支持类似StringBuilder那样的链式调用,本小节中终结方法包括count和forEach;
void forEach(Consumer<? super T> action);
该方法接收一个Consumer接口函数,会将每一个流元素交给该方法处理;
Stream<String> stream = Stream.of("你好!","Hello!","哈哈!");
stream.forEach(System.out::println);
//你好!
//Hello!
//哈哈!
Stream<T> fliter(Predicate<? super T> predicate);
将一个流转换为一个子集流;
Predicate接口是用于判断的接口;
Stream<String> stream = Stream.of("你好!","Hello!","哈哈!");
Stream<String> stream1 = stream.filter((word)->word.startsWith("你"));
stream1.forEach(System.out::println);//你好!
Stream流只能使用一次;
Stream<String> stream = Stream.of("你好!","Hello!","哈哈!");
Stream<String> stream1 = stream.filter((word)->word.startsWith("你"));
stream1.forEach(System.out::println);//你好!
//Stream流是管道流,只能使用一次
stream1.forEach(System.out::println);//报错
//java.lang.IllegalStateException: stream has
// already been operated upon or closed
<R> Stream<R> map(Function<? super T, ? extends R> mapper );
将流中的元素映射到另一个流中;
Function接口的抽象方法R apply(T t)可以将T类型转换成R类型,而这种转换的动作,成为映射;
Stream<String> stream = Stream.of("1","2","3");
Stream<Integer> stream1 = stream.map(Integer::parseInt);
stream1.forEach(System.out::println);
//1
//2
//3
long count
统计个数,相当于集合的size方法;
Stream<String> stream = Stream.of("1","2","3");
System.out.println(stream.count());//3
Stream<T> limit(long maxSize);
截取前N个元素;
Stream<String> stream = Stream.of("1","2","3");
stream.limit(3).forEach(System.out::println);
//1
//2
//3
Stream<T> skip(long n);
跳过前N个元素;
Stream<String> stream = Stream.of("1","2","3");
stream.skip(2).forEach(System.out::println);//3
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
将两个流合并成一个流;
Stream<String> stream1 = Stream.of("1","2","3");
Stream<String> stream2 = Stream.of("4","5","6");
Stream.concat(stream1,stream2).forEach(System.out::println);
//1
//2
//3
//4
//5
//6