文章目录
Stream流
一:常用的函数式接口
1.Predicate接口
1.1:Predicate接口概述
a:Predicate接口做什么用的
Predicate接口里面有一个抽象方法Test方法(该方法有一个参数有boolean返回值),
还有几个默认方法(与,或,非),通常用于判断数据类型。
1.2:Predicate接口常用方法
a:抽象方法(test)
public class Demo02 {
public static void main(String[] args) {
panBoolean(s->s.startsWith("h"),"h123 ");
}
public static void panBoolean(Predicate<String> predicate,String str){
//Predicate就是一个接口,含有唯一的抽象方法,通常用于筛选数据的数据类型
boolean bo = predicate.test(str);
System.out.println(bo);
}
}
b:默认方法(and, or, negate)
and:
public class Demo03 {
public static void main(String[] args) {
panBoolean(s1 ->
s1.startsWith("h")
, s2 ->
s2.length() > 3
, "aslffja");
}
public static void panBoolean(Predicate<String> predicate1, Predicate<String> predicate2, String str) {
// boolean b1 = predicate1.test(str);
// boolean b2 = predicate2.test(str);
// System.out.printlin(b1&&b2);
//和上面是一样的。
System.out.println(predicate1.and(predicate2).test(str));
}
}
or:代码的执行逻辑和and方法一样。
negate:
public class Demo04 {
public static void main(String[] args) {
panBoolean(s -> s.startsWith("h"),"hewa");
}
public static void panBoolean(Predicate<String> predicate,String str){
//System.out.println(!predicate.test(str));
//和上面是等价的
System.out.println(predicate.negate().test(str));
}
}
1.3:and,or和negate底层
//predicate1.and(predicate2):返回一个(t) -> test(t) && other.test(t)对象。
//test(str):就是调用(t) -> test(t) && other.test(t),将str穿给(t) -> test(t) && other.test(t);并执行。
predicate1.and(predicate2).test(str)
a:and底层代码
default Predicate<T> and(Predicate<? super T> other) {
//用于判断参数是否为空,如果为空抛出空指针异常
Objects.requireNonNull(other);
//
return (t) -> test(t) && other.test(t);
}
b:or方法的底层代码和and方法类似
//predicate1.negate():返回一个Predicate子对象为(t) -> !test(t);
//test();:是调用Predicate的实现类的test方法,其实也就是执行(t) -> !test(t)。
//将str传递给(t) -> !test(t);中的t。
predicate1.negate().test(str);
c:negate的底层代码
default Predicate<T> negate() {
return (t) -> !test(t);
}
2.Function接口
2.1:Function接口概述
a:Function接口是做什么的
是一个函数式接口,里面有个抽象方法apply(有一个参数和一个返回值)。
默认方法为andThen。通常用于数据转换。
2.2:Function接口常用方法
a:抽象方法(apply)
//将“100”转化为100.
public class Demo05 {
public static void main(String[] args) {
changeState(num->Integer.parseInt(num),"100");
}
public static void changeState(Function<String, Integer> function, String str) {
Integer i = function.apply(str);
System.out.println(i);
}
}
b:默认方法(andThen)
//表示先后执行
public class Demo06 {
public static void main(String[] args) {
changeState(s1->Integer.parseInt(s1),s2->100,"10");
}
public static void changeState(Function<String,Integer> function,Function<Integer,Integer> function1,String str){
//表示先执行function的apply方法,再执行function1的方法。
Integer i2 = function.andThen(function1).apply(str);
System.out.println("i2 = " + i2);
}
}
1.3:andThen底层代码
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
//对参数进行判断
Objects.requireNonNull(after);
//function.andThen(function1).apply(str)
//function.andThen(function1)返回一个 Function的实现类对象
//apply(str):执行(T t) -> after.apply(apply(t));,并把str给t.
return (T t) -> after.apply(apply(t));
}
二:Stream流
1.Stream的概述
1.1:为什么引出Stream流
用于解决用于解决已有集合类库,和数组既有的弊端。
1.2:Stream流是什么
“Stream流”其实是一个集合元素的函数模型,它并不是集合,也不是数据结构,
其本身并不存储任何元素(或其地址值)
1.3:注意
Stream流对象只能被使用,使用一次后不能被再次调用其他方法。
Stream是Java 8新加入的最常用的流接口。
2.怎样获取Stream流(三种)
2.1:Collection转化为Stream流
Collection<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
2.2:Map集合转化为Stream流
叙述:
因为Map集合是双列集合无法直接获取流,需要将双列集合转化为单列集合
代码:
Map<String, Integer> map = new HashMap<>();
Set<Map.Entry<String, Integer>> entries = map.entrySet();
Stream<Map.Entry<String, Integer>> stream1 = entries.stream();
Set<String> keys = map.keySet();
Stream<String> stream2 = keys.stream();
Collection<Integer> values = map.values();
Stream<Integer> stream3 = values.stream();
2.3:数组转化为Stream流
//必须是引用数据类型。
Integer[] arr = {1,1,3,4};
//利用Stream的的静态方法,of方法的参数为可变数据类型
Stream<Integer> arr1 = Stream.of(arr);
3.Stream流中常用的方法
3.1:过滤方法(filter)
1.实现代码:
Stream<String> stream1 = Stream.of("张无忌", "张三丰", "周芷若", "d", "aa");
//filter方法需要一个Predicate类用来筛选,满足条件加入流。
//filter方法中需要一个Predicate实现类做参数,对流实行过滤。
Stream<String> stream2 = stream1.filter(s -> s.length() >= 3);
2.filter方法的执行过程:
将流的每个元素当作参数分别放到,Lambda表达式中进行筛选,如果为true放入流中
否则舍弃。
3.2:将一个流转为另外一个流,元素数据类型不一样(map)
//根据数组获取Stream流
Stream<String> stream = Stream.of("10", "110", "100");
//将Stream流中的每一个元素进行类型转换
Stream<Integer> stream1 = stream.map(s -> Integer.parseInt(s));
//将流转化为数组。
Object[] objects = stream1.toArray();
//将数组转化为字符串
System.out.println(Arrays.toString(objects));
总结:
map方法的执行顺序和filter方法的执行顺序一样。
3.2:取出流中每个元素(forEach)
Stream<String> stream = Stream.of("10", "110", "100");
//需要一个消费者接口(consumer)
stream.forEach(s-> System.out.println(s));
3.3:求出流的长度(count)
long count = stream.count();
3.4:将两个流链接到一起(Concat静态方法)
//stream1接到stream流的后面
Stream<String> concat = Stream.concat(stream, stream1);
3.6:取前几个元素(limite),跳过前几个元(skip)
//取出流的前几个元素放到另外一个流中
Stream<String> stream = Stream.of("10", "110", "100");
Stream<String> limit = stream.limit(2);
//跳过前几个元素
Stream<String> stream1 = Stream.of("1", "2", "3");
Stream<String> skip = stream1.skip(1);
3.7:总结
a:链式调用方法:filter concat(静态方法) map limit skip
b:非链式调用:ForEach(无返回值), count(返回值为整数)
4.将流中的元素收集到集合和数组中
4.1:将流中的元素收集到集合
a;用到的方法
//使用 Collector对此流的元素执行 mutable reduction操作
R collect(Collector collector)
Collector:收集器接口,通常用Collectors的工具类来获取Collector实现类
b:代码
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5,5,5,5);
//将流中的元素放到list集合中
List<Integer> collect = stream.collect(Collectors.toList());
Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5,5,5,5);
//将流中的元素放到set集合中
Set<Integer> set = stream1.collect(Collectors.toSet());
4.2:将流中的元素收集到数组中
a:
Stream<Integer> stream = Stream.of(1, 2, 3, 4);
//将流收集为Object类型的数组。
Object[] objects = stream.toArray();
System.out.println(Arrays.toString(objects));
b:
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5,5,5,5);
Integer[] integers = stream.toArray(a -> new Integer[a]);
5.总结
a:
今天学习了Predicate接口,里面有个test方法(需要一个参数,有一个boolean返回值),
还有一些静态方法and,or,negate(对两个结果进行与,或,非),通常称为数据的判断
类型。
b:
Function接口有一个抽象方法apply(有一个参数,有返回值),还有静态方法andThen
表示。通常称为数据转化器。
c:
Stream是一个模型,可以将集合,数组转化为流,然后可以利用流的一些方法对数
据进行操作比如筛选(需要Predicate实现类参数,)将流中的数据转化为另外一种
类型(需要Function中的实现类)遍历每一个元素(需要一个Costumer一个实现类)
。获取流元素的个数。获取流的前几个元素,获取流的后几个元素然后又将流中的数
据收集到集合数组中。