郑州网站制作工作室,id和wordpress,网页线上开发制作,国家商标注册官网文章目录 Stream流如何获取流水线Stream流中间方法Stream终结方法 方法引用引用静态方法引用成员方法引用构造方法类名引用成员方法引用数组构造方法 Stream流
Stream流是JDK8中提供的一种新特性
Stream流的使用步骤#xff1a;
先得到Stream流#xff0c;把数据放到流中使… 文章目录 Stream流如何获取流水线Stream流中间方法Stream终结方法 方法引用引用静态方法引用成员方法引用构造方法类名引用成员方法引用数组构造方法 Stream流
Stream流是JDK8中提供的一种新特性
Stream流的使用步骤
先得到Stream流把数据放到流中使用中间方法对流水线上的数据进行操作 中间方法过滤、转换方法调用完毕后还可以调用其他方法 使用终结方法对流水线上的数据进行操作 终结方法统计、打印最后一步操作方法调用完毕之后不能再去调用其他方法
如何获取流水线
获取方式方法名说明单例集合default StreamE stream()Collection中的默认方法双列集合无无法直接使用stream流数组public static T StreamT stream(T[] array)Arrays工具类中的静态方法零散数据public staticT StreamTof(T… values)Stream接口中的静态方法需要同种数据类型
单列集合获取Stream流
//集合的批量添加
ListString list new ArrayListString(){{add(张无忌);add(周芷若);add(赵敏);add(张三丰);add(张翠山);add(王二麻子);add(谢广坤);add(马超);add(张良);}
};
// 获取stream流并打印
list.stream().forEach(s - System.out.println(s));双列集合获取Stream流
MapInteger,String map new HashMapInteger,String(){{put(1,张无忌);put(2,周芷若);put(3,赵敏);}
};
// 直接获取map中的key
map.keySet().stream().forEach(k - System.out.println(k));
// 获取map中的value
map.values().stream().forEach(v - System.out.println(v));
// 获取键值对
map.entrySet().stream().forEach(e- System.out.println(e));数组获取Stream流
String[] str {张无忌,周芷若,赵敏,张三丰,张翠山,王二麻子,谢广坤,马超,张良};
// 数组转集合
ListString collect Arrays.stream(str).collect(Collectors.toList());
System.out.println(collect);零散数据获取Stream流
前提零散数据类型是一样的
Stream.of(张无忌,周芷若,赵敏,张三丰,张翠山,王二麻子,谢广坤,马超,张良).forEach(s - System.out.println(s));Stream流中间方法
名称说明StreamT filter(Predicate? super T predicate)过滤StreamT limit(long maxSize)获取前几个元素StreamT skip(long n)跳过前几个元素StreamT distinct()元素去重依赖(hashCode和equals方法)static T StreamT concat(Stream a, Stream b)合并a和b两个流为一个流StreamR map(FunctionT, R mapper)转换流中的数据类型
注意1:中间方法返回新的Stream流原来的Stream流只能使用一次建议使用链式编程注意2:修改Stream流中的数据不会影响原来集合或者数组中的数据
filter方法
该方法返回true表示保留该数据false表示过滤掉该数据
public static void main(String[] args) {//集合的批量添加ListString list new ArrayListString() {{add(张无忌);add(周芷若);add(赵敏);add(张三丰);add(张翠山);add(王二麻子);add(谢广坤);add(马超);add(张良);}};// s表示集合里的每一条数据list.stream().filter(new PredicateString() {Overridepublic boolean test(String s) {return false;}});// 打印以张开头的前两条数据list.stream().filter(s - s.startsWith(张)).limit(2).forEach(s - System.out.println(s));}concat方法
concat方法是Stream的静态方法作用是将两个Stream流合并成一个注意如果两个流的数据类型不一致就会将类型提示为他们共同的父类。
//集合的批量添加ListString list new ArrayListString() {{add(张无忌);add(周芷若);add(赵敏);add(张三丰);add(张翠山);add(王二麻子);add(谢广坤);add(马超);add(张良);}};Stream.concat(list.stream(),list.stream()).forEach(s - System.out.println(s));map方法
打印每个人的年龄
public static void main(String[] args) {//集合的批量添加ListString list new ArrayListString() {{add(张无忌-22);add(周芷若-20);add(赵敏-20);add(张三丰-70);add(张翠山-50);add(王二麻子-20);add(谢广坤-44);add(马超-35);add(张良-30);}};// 匿名内部类写法list.stream().map(new FunctionString, Integer() {Overridepublic Integer apply(String s) {String[] split s.split(-);int ret Integer.parseInt(split[1]);return ret;}}).forEach(s-System.out.println(s));// lambda写法,在forEach中s已经编程整形list.stream().map(s-Integer.parseInt(s.split(-)[1])).forEach(s-System.out.println(s));}
}Stream终结方法
名称说明void forEach(Consumer action)遍历long count()统计toArray()收集流中的数据放到数组中collect(Collector collertor)收集流中的数据放到集合中
toArray()方法
public static void main(String[] args) {//集合的批量添加ListString list new ArrayListString() {{add(张无忌);add(周芷若);add(赵敏);add(张三丰);add(张翠山);add(王二麻子);add(谢广坤);add(马超);add(张良);}};// 匿名内部类写法String[] array list.stream().toArray(new IntFunctionString[]() {/**** param value 数组的容量* return*/Overridepublic String[] apply(int value) {return new String[value];}});System.out.println(Arrays.toString(array));// lambda写法String[] array1 list.stream().toArray(value - new String[value]);System.out.println(Arrays.toString(array1));}collect方法
收集为List或者Set是比价简单的
public static void main(String[] args) {//集合的批量添加ListString list new ArrayListString() {{add(张无忌-男-22);add(周芷若-女-20);add(赵敏-女-20);add(张三丰-男-66);add(张翠山-男-55);add(谢广坤-男-35);add(马超-男-30);add(张良-男-29);}};// 将所有男性收集到一个List中ListString ret list.stream().filter(s - 男.equals(s.split(-)[1])).collect(Collectors.toList());// 将素所有女性收集到一个Set中SetString set list.stream().filter(s - 女.equals(s.split(-)[1])).collect(Collectors.toSet());System.out.println(ret);System.out.println(set);}来看一下收集到Map里将姓名和年龄形成一个键值对。
注意使用toMap收集流中的数据时key是不能重复的否则会抛出异常
public static void main(String[] args) {//集合的批量添加ListString list new ArrayListString() {{add(张无忌-男-22);add(周芷若-女-20);add(赵敏-女-20);add(张三丰-男-66);add(张翠山-男-55);add(谢广坤-男-35);add(马超-男-30);add(张良-男-29);}};// 匿名内部类写法/*** toMap的第一个函数接口参数* 泛型参数key 表示流的数据类型* 泛型参数 value: 表示要转换Map的key的数据类型* toMap的第二个函数接口参数* 泛型参数key 表示流的数据类型* 泛型参数 value: 表示要转换Map的value的数据类型*/MapString,Integer map1 list.stream().collect(Collectors.toMap(new FunctionString, String() {/*** 该方法的参数就是流中的元素* 该方法的返回值就是Map的key* param s the function argument* return*/Overridepublic String apply(String s) {return s.split(-)[0];}},new FunctionString, Integer() {/*** 该方法的参数就是流中的元素* 该方法的返回值就是Map的value* param s the function argument* return*/Overridepublic Integer apply(String s) {return Integer.parseInt(s.split(-)[2]);}}));// lambda写法MapString ,Integer map2 list.stream().collect(Collectors.toMap(s - s.split(-)[0],s-Integer.parseInt(s.split(-)[2])));System.out.println(map1);System.out.println(map2);
}方法引用
方法引用就是把已经有的方法拿过来用当做函数式接口中抽象方法的方法体
使用方法引用需要注意以下4点
引用处必须是函数式接口被引用的方法必须已经存在被引用方法的形参和返回值需要跟抽象方法保持一致被引用方法的功能要满足当前需求
举个例子我们要对一个数组进行降序排序。
public static void main(String[] args) {Integer[] arr {1,6,8,3,4,6,7,5,2,9};// 使用匿名内部类Arrays.sort(arr, new ComparatorInteger() {Overridepublic int compare(Integer o1, Integer o2) {return o2-o1;}});// 使用lambda表达式Arrays.sort(arr, (o1, o2) - o2-o1);System.out.println(Arrays.toString(arr));
}我们可以通过方法引用的方式来进行
Arrays.sort的第二个参数比较规则是函数式接口满足要求其余3点也满足就可以使用方法引用。
public static void main(String[] args) {Integer[] arr {1,6,8,3,4,6,7,5,2,9};// 使用方法引用Arrays.sort(arr, Main::cmp);System.out.println(Arrays.toString(arr));}
public static int cmp(int a,int b){return b-a;
}::是一个方法引用符号
引用静态方法
格式类名::静态方法示例Integer::parseInt
比如将一组字符串数组转换成整形数字直接将Integer的静态方法拿过来用即可
public static void main(String[] args) {ListString list new ArrayListString(){{add(1);add(2);add(3);add(4);add(5);}};// 匿名内部类写法ListInteger ret1 list.stream().map(new FunctionString, Integer() {Overridepublic Integer apply(String s) {return Integer.parseInt(s);}}).collect(Collectors.toList());System.out.println(ret1);// 使用方法引用写法ListInteger ret2 list.stream().map(Integer::parseInt).collect(Collectors.toList());System.out.println( ret2);
}引用成员方法
格式 对象::成员方法
其他类其他对象::方法名本类this::方法名引用处不能是静态方法父类super::方法名引用处不能是静态方法
需求打印性张且名字长度为3个字人
调用其他类的成员方法
class Test{public boolean filter(String s) {return s.startsWith(张) s.length() 3;}
}
public class Main {public static void main(String[] args) {//集合的批量添加ListString list new ArrayListString() {{add(张无忌);add(周芷若);add(赵敏);add(张三丰);add(张翠山);add(谢广坤);add(马超);add(张良);}};// 匿名内部类写法list.stream().filter(new PredicateString() {Overridepublic boolean test(String s) {return s.startsWith(张) s.length() 3;}}).forEach(s - System.out.println(s));// 方法引用引用其他类方法Test test new Test();list.stream().filter(test::filter).forEach(s - System.out.println(s));}}引用本类的成员方法
需求打印性张且名字长度为3个字人
public class Main {public boolean filter(String s) {return s.startsWith(张) s.length() 3;}public void main(String[] args) {//集合的批量添加ListString list new ArrayListString() {{add(张无忌);add(周芷若);add(赵敏);add(张三丰);add(张翠山);add(谢广坤);add(马超);add(张良);}};// 方法引用引用本类类方法list.stream().filter(new Main()::filter).forEach(s - System.out.println(s));}}引用父类的成员方法
class Test {public boolean filter(String s) {return s.startsWith(张) s.length() 3;}
}public class Main extends Test {public boolean filter(String s) {return s.startsWith(张) s.length() 3;}public void func() {//集合的批量添加ListString list new ArrayListString() {{add(张无忌);add(周芷若);add(赵敏);add(张三丰);add(张翠山);add(谢广坤);add(马超);add(张良);}};// 方法引用引用父类方法list.stream().filter(super::filter).forEach(System.out::println);}}引用构造方法
格式类名::new
需求将字符串张三-22构成User对象
class User {String username;int age;public User(String username, int age) {this.username username;this.age age;}public User(String str) {String[] split str.split(-);this.username split[0];this.age Integer.parseInt(split[1]);}Overridepublic String toString() {return User{ username username \ , age age };}
}public class Main {public boolean filter(String s) {return s.startsWith(张) s.length() 3;}public static void main(String[] args) {//集合的批量添加ListString list new ArrayListString() {{add(张无忌-22);add(周芷若-20);add(赵敏-20);add(张三丰-60);add(张翠山-35);}};// 匿名内部类写法ListUser userList1 list.stream().map(new FunctionString, User() {Overridepublic User apply(String str) {String[] split str.split(-);return new User(split[0], Integer.parseInt(split[1]));}}).collect(Collectors.toList());System.out.println(userList1);// 使用构造方法引用写法拿User类的构造方法作为参数ListUser userList2 list.stream().map(User::new).collect(Collectors.toList());System.out.println(userList2);}}类名引用成员方法
格式类名::成员方法示例String::toUpperCase
这种通过类名引用成员方法的方式有点特别需要遵循以下规则
方法引用的规则
需要有函数式接口被引用的方法必须已经存在被引用方法的形参需要跟抽象方法的第一个参数到最后一个形参保持一致返回值需要保持一致被引用方法的功能需要满足当前的需求
抽象方法形参注意事项
第一个参数表示被引用方法的调用者决定了可以引用哪些类的方法在Stream流当中第一个参数一般都表示流里面的每一个数据假设流里面的数据是字符串那么使用这种方式进行方法引用只能引用String这个类中的方法第二个参数到最后一个参数跟被引用方法的形参保持一致如果没有第二个参数说明被引用的方法需要是无参的成员方法
需求将一堆字符串都转换成大写
首先Function是一个函数式接口它只有一个抽象方法applyapply方法的第一个形参是String类型那么就觉得了只能引用String中的方法apply方法没有第二个形参说明引用的方法需要是无参的那么引用String中的toUpperCase是符合要求的
public static void main(String[] args) {ListString stringList Arrays.asList(aa,bb,cc,dd);// 匿名内部类写法ListString ret1 stringList.stream().map(new FunctionString, String() {Overridepublic String apply(String s) {return s.toUpperCase();}}).collect(Collectors.toList());System.out.println(ret1);// 方法引用写法ListString ret2 stringList.stream().map(String::toUpperCase).collect(Collectors.toList());System.out.println(ret2);}public String toUpperCase() {return toUpperCase(Locale.getDefault());
}局限性:
不能引用所有类中的成员方法。是跟抽象方法的第一个参数有关这个参数是什么类型的那么就只能引用这个类中的方法
引用数组构造方法
格式数据类型[]:new示例int[]::new
需求将List中的数据放到一个新数组中
public static void main(String[] args) {ListInteger list new ArrayListInteger(){{add(1);add(2);add(3);add(4);add(5);}};// 匿名内部类写法Integer[] array list.stream().toArray(new IntFunctionInteger[]() {Overridepublic Integer[] apply(int value) {return new Integer[value];}});System.out.println(Arrays.toString(array));// 方法引用写法Integer[] array2 list.stream().toArray(Integer[]::new);System.out.println(Arrays.toString(array2));
}