视频网站开发费用,常州模板建站哪家好,重庆建设集团,百度文库官网1 Stream流
1.1 Stream流优化过滤集合
传统方式
用一个循环过滤姓张的人用一个循环过滤名字长度大于2的人 public static void main(String[] args) {ArrayListString list new ArrayList();list.add(张三);list.add(李四);list.a…1 Stream流
1.1 Stream流优化过滤集合
传统方式
用一个循环过滤姓张的人用一个循环过滤名字长度大于2的人 public static void main(String[] args) {ArrayListString list new ArrayList();list.add(张三);list.add(李四);list.add(张三三);list.add(张四四);list.add(李四四);ArrayListString newlist new ArrayList();for(String s: list){if(s.startsWith(张)s.length()2){listWithZhang.add(s);}}for(String s: newlist){System.out.println(s);}}Stream流 JDK1.8后出现关注做什么而不是怎么做 public static void main(String[] args) {ArrayListString list new ArrayList();list.add(张三);list.add(李四);list.add(张三三);list.add(张四四);list.add(李四四);list.stream().filter((name)-name.startsWith(张)).filter((name)-name.length()2).forEach((name)-{System.out.println(name);});}1.2 流式思想概述
拼接流式模型建立一个生产线按照生产线来生产商品。
当使用一个流的时候通常包括三个基本步骤
获取一个数据源source→数据转换→执行操作获取想要的结果.
每次转换原有 Stream 对象不改变返回一个新的 Stream 对象可以有多次转换这就允许对其操作可以像链条一样排列变成一个管道。
1.3 获取流
java.util.stream.StreamT 是Java 8新加入的最常用的流接口。 这并不是一个函数式接口。
获取一个流有以下几种常用的方式
所有的Collection集合都可以通过 stream 默认方法获取流Stream 接口的静态方法 of 可以获取数组对应的流。 public static void main(String[] args) {//集合调用stream方法可以获得ArrayListString list new ArrayList();StreamString stream1 list.stream();//数组可以用Stream.of获得StreamInteger stream6 Stream.of(1, 2, 3, 4, 5, 6);Integer[] arr {1, 2, 3, 5};StreamInteger steam7 Stream.of(arr);} 流的特点Stream流属于管道流只能使用一次第一个流使用完毕就会关闭这个流就不可以再调用其他方法了。
1.4 常用方法
流模型的操作很丰富这里介绍一些常用的API。这些方法可以被分成两种
延迟方法返回值类型仍然是Stream 接口自身类型的方法因此支持链式调用。除了终结方法外其余方法均为延迟方法。终结方法返回值类型不再是Stream 接口自身类型的方法因此不再支持类似StringBuilder 那样的链式调用。例如count 和forEach方法。
forEach方法forEach的参数是Consumer //forEach的参数的Consumer//Consumer接口是一个消费型的函数式接口可以传递lambda表达式消费数据public static void main(String[] args) {StreamString stream Stream.of(张三, 李四, 王五);stream.forEach(name- System.out.println(name));}filter方法filter的参数是Predicate用于将一个流转换成另一个子集流 //forEach的参数是该接口接收一个Predicate//函数式接口参数可以是一个Lambda或方法引用作为筛选条件。//test方法将会产生一个boolean值结果代表指定的条件是否满足。//如果结果为true那么Stream流的filter 方法//将会留用元素如果结果为false那么filter 方法将会舍弃元素。public static void main(String[] args) {StreamString stream Stream.of(张三, 张四,李四, 王五);StreamString stream1 stream.filter((name) - {return name.startsWith(张);});stream1.forEach(name- System.out.println(name));}map方法 如果需要将流中的元素映射到另一个流中可以用map。可以将T类型的流转换为R类型的流。java.util.stream.Function 函数式接口其中唯一的抽象方法为apply。这可以将一种T类型转换成为R类型而这种转换的动作就称为“映射”。
将integer类型转换为string类型 public static void main(String[] args) {StreamInteger stream Stream.of(1, 2, 3, 4, 5);StreamString stream2 stream.map((Integer i) - {return String.valueOf(i);});stream2.forEach((s)- System.out.println(s));}count方法 用于统计Stream流中的元素个数。正如旧集合Collection 当中的size 方法一样流提供count 方法来数一数其中的元素个数。count方法返回值是long类型的整数是终结方法之后不能再继续调用其他方法。 public static void main(String[] args) {StreamInteger stream Stream.of(1, 2, 3, 4, 5);long count stream.count();System.out.println(count);}limit方法可以对流进行截取。参数是long类型的整数。属于延迟方法可以继续调用其他方法。如果集合当前长度大于参数则进行截取否则不进行操作即还是原流。 public static void main(String[] args) {StreamInteger stream Stream.of(1, 2, 3, 4, 5);stream.limit(3).forEach((num)- System.out.println(num));}skip方法可以跳过前几个元素获取一个截取之后的新流。参数超过元素个数返回空流。 public static void main(String[] args) {StreamInteger stream Stream.of(1, 2, 3, 4, 5);stream.skip(3).forEach((num)- System.out.println(num));}concat方法组合两个流为一个流。concat是静态方法通过接口名调用。 public static void main(String[] args) {StreamInteger stream1 Stream.of(1, 2, 3, 4, 5);StreamString stream2 Stream.of(a,b,c,d);Stream.concat(stream1,stream2).forEach((s)- System.out.println(s));}1.5 练习-集合元素处理 现在有两个ArrayList 集合存储队伍当中的多个成员姓名要求使用传统的for循环或增强for循环依次进行以下若干操作步骤 第一个队伍只要名字为3个字的成员姓名 第一个队伍筛选之后只要前3个人 第二个队伍只要姓张的成员姓名 第二个队伍筛选之后不要前2个人 将两个队伍合并为一个队伍 根据姓名创建Person 对象 打印整个队伍的Person对象信息。 Stream方式 public static void main(String[] args) {ArrayListPerson list1 new ArrayList();list1.add(new Person(李白));list1.add(new Person(杜甫));list1.add(new Person(李清照));list1.add(new Person(王勃));list1.add(new Person(刘禹锡));list1.add(new Person(辛弃疾));list1.add(new Person(龚自珍));ArrayListPerson list2 new ArrayList();list2.add(new Person(李四));list2.add(new Person(王五));list2.add(new Person(张一));list2.add(new Person(张二));list2.add(new Person(张三));StreamPerson newlist1 list1.stream().filter((person) - {return person.getName().length() 3;}).limit(3);StreamPerson newlist2 list2.stream().filter((person) - {return person.getName().startsWith(张);}).skip(2);Stream.concat(newlist1, newlist2).forEach((person)- System.out.println(person));}2 方法引用
2.1 应用简化lambda
双冒号:: 为引用运算符而它所在的表达式被称为方法引用。如果Lambda要表达的函数方案已经存在于某个方法的实现中那么则可以通过双冒号来引用该方法作为Lambda的替代者。
例如上方代码中的最后一句可以等价为
Stream.concat(newlist1, newlist2).forEach((person)- System.out.println(person));
Stream.concat(newlist1, newlist2).forEach(System.out::println);2.2 通过对象名引用成员方法
自定义一个接口
public interface Printable {void print(String s);
}自定义一个类及其成员方法
public class MethodRerObject {public void printUpperCaseString(String str){System.out.println(str.toUpperCase());}
}测试
public class Test {//通过对象名引用成员方法//前提对象名存在成员方法存在public static void printString(Printable p){p.print(Hello);}public static void main(String[] args) {//用lambdaprintString((s)-{MethodRerObject obj new MethodRerObject();obj.printUpperCaseString(s);});//方法引用优化//对象和成员方法都存在MethodRerObject obj new MethodRerObject();printString(obj::printUpperCaseString);}
}2.3 通过类名引用静态成员方法
定义一个函数式接口
FunctionalInterface
public interface Calcable {int calAbs(int num);
}定义一个方法传递接口和整数
public class Test {public static int method(int number, Calcable c){return c.calAbs(number);}public static void main(String[] args) {//调用method方法int result method(-10, (num) - Math.abs(num));System.out.println(result);//使用方法引用优化 Math存在 abs的静态方法也存在int result2 method(-10, Math::abs);System.out.println(result2);}
}2.4 通过super引用父类成员方法
定义函数式接口
public interface Greatable {void great();
}定义父类
public class Human {public void sayHello(){System.out.println(Hello, i am human);}
}定义子类
public class Man extends Human{Overridepublic void sayHello(){System.out.println(Hello, i am man);}public void great(Greatable g){g.great();}public void show(){great(()-{Human h new Human();h.sayHello();});//通过父类调用great(()-{super.sayHello();});//通过父类引用great(super::sayHello);}public static void main(String[] args) {new Man().show();}
}2.5 通过this引用本类成员方法
public interface Richable {void buy();
}public class Husband {public void buyHouse(){System.out.println(买房子);}public void marry(Richable r){r.buy();}public void soHappy(){//this和buyHouse都是以及存在的 可以直接用this来引用本类方法//marry(()-this.buyHouse());marry(this::buyHouse);}public static void main(String[] args) {new Husband().soHappy();}
}2.6 类的构造器引用
自定义一个Person类自定义一个创建Person的接口
public interface PersonBuilder {Person buildPerson(String name);
}public class Test {public static void printName(String name, PersonBuilder pb){Person person pb.buildPerson(name);System.out.println(person.getName());}public static void main(String[] args) {//调用method方法printName(张三,(name)-new Person(name));//使用方法引用优化 Person的构造方法已知 创建对象new已知printName(李四, Person::new);}
}2.7 数组的构造器引用
FunctionalInterface
public interface ArrayBuilder {int[] buiderArray(int length);
}public class Test {public static int[] createArray(int len, ArrayBuilder ab){return ab.buiderArray(len);}public static void main(String[] args) {//调用method方法int[] array createArray(10, (len) -new int[len]);System.out.println(array.length);//使用方法引用优化lambda 已知创建的是int类型的数组 数组的长度已知int[] array1 createArray(10, int[]::new);System.out.println(array1.length);}
}