流与集合相比的优点
流的延迟执行特点
集合、映射或数组获取流
常用的流操作
输出语句的方法引用
使用类和数组的构造器引用
public class StreamDemo { //流控制,打印 @Test public void test1() { List<String> data = new ArrayList<String>(); data.add("张无忌"); data.add("着迷"); data.add("张三丰"); data.add("百里一组"); data.add("二蛋二狗子"); data.stream().filter( s -> s.startsWith("张")) .filter(s -> s.length() == 3).forEach(System.out::println); } //获取流 @Test public void test2() { List<String> data = new ArrayList<String>(); Stream<String> stream = data.stream(); HashMap<String, Object> data2 = new HashMap<>(); Stream<String> keys = data2.keySet().stream(); Stream<Object> values = data2.values().stream(); //数组 String[] arr = {"张三", "李四", "张三丰"}; Stream<String> arr1 = Stream.of(arr); arr1.filter(s -> s.startsWith("张")).forEach(name -> System.out.println(name)); //arr1.forEach(name-> System.out.println(name)); } /** * 果需要将流中的元素映射到另一个流中,可以使用 map 方法。方法签名: * 该接口需要一个 Function 函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型的流 */ @Test public void test3() { String[] arr = {"张三", "李四", "张三丰"}; Stream<String> data = Stream.of("12", "13", "22"); Stream<Integer> result = data.map(str -> Integer.parseInt(str)); result.forEach(str -> System.out.println(str)); } /** * 如旧集合 Collection 当中的 size 方法一样,流提供 count 方法来数一数其中的元素个数: */ @Test public void test4() { String[] arr = {"张三", "李四", "张三丰"}; Stream<String> arr1 = Stream.of(arr); Stream<String> result = arr1.filter(s -> s.startsWith("张")); System.out.println(result.count()); } /** * 取用前几个:limit * limit 方法可以对流进行截取,只取用前n个。方法签名: */ @Test public void test5() { String[] arr = {"张三", "李四", "张三丰"}; Stream<String> arr1 = Stream.of(arr); Stream<String> limit = arr1.limit(1); Stream<String> result = limit.filter(s -> s.startsWith("张")); System.out.println(result.count()); } /** * 如果希望跳过前几个元素,可以使用 skip 方法获取一个截取之后的新流 */ @Test public void test6() { String[] arr = {"张三", "李四", "张三丰"}; Stream<String> arr1 = Stream.of(arr); Stream<String> skip = arr1.skip(1); System.out.println(skip.count()); } /** * 如果希望跳过前几个元素,可以使用 skip 方法获取一个截取之后的新流 */ @Test public void test7() { String[] arr = {"张三", "李四", "张三丰"}; Stream<String> arr1 = Stream.of("张三丰"); Stream<String> arr2 = Stream.of("张无极"); Stream<String> concat = Stream.concat(arr1, arr2); concat.forEach(System.out::println); } /** * 1. 第一个队伍只要名字为3个字的成员姓名;存储到一个新集合中。 * 2. 第一个队伍筛选之后只要前3个人;存储到一个新集合中。 * 3. 第二个队伍只要姓张的成员姓名;存储到一个新集合中。 * 4. 第二个队伍筛选之后不要前2个人;存储到一个新集合中。 * 5. 将两个队伍合并为一个队伍;存储到一个新集合中。 * 6. 根据姓名创建 Person 对象;存储到一个新集合中。 * 7. 打印整个队伍的Person对象信息。 */ class Person { private String name; 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 + '\'' + '}'; } } @Test public void test8() { List<String> one = new ArrayList<String>(); one.add("迪丽热巴"); one.add("宋远桥"); one.add("苏星河"); one.add("石破天"); one.add("石中玉"); one.add("老子"); one.add("庄子"); one.add("洪七公"); List<String> two = new ArrayList<String>(); two.add("古力娜扎"); two.add("张无忌"); two.add("赵丽颖"); two.add("张三丰"); two.add("尼古拉斯赵四"); two.add("张天爱"); two.add("张二狗"); Stream<String> oneConcat = one.stream().filter(name -> name.length() == 3).limit(3); Stream<String> twoConcat = two.stream().filter(name -> name.startsWith("张")).skip(2); Stream.concat(oneConcat, twoConcat).map(Person::new).forEach(System.out::println); } /** * :: 为“方法引用”,而双冒号是一种新的语法 * Lambda表达式写法: s -> System.out.println(s); * 方法引用写法: System.out::println * 第一种语义是指:拿到参数之后经Lambda之手,继而传递给 System.out.println 方法去处理。 * 第二种等效写法的语义是指:直接让 System.out 中的 println 方法来取代Lambda。两种写法的执行效果完全一 * 样,而第二种方法引用的写法复用了已有方案,更加简洁。 */ /** * 通过函数引用静态方法 */ @Test public void test9() { test9Demo(s->{ System.out.println(s); }); test9Demo(System.out::println); } public void test9Demo(Printable p) { p.print("hello"); } class ChildInterfacd implements ParentInterface{ @Override public String method(String a) { System.out.println(a); return null; } } /*** * 通过对象名引用方法 */ @Test public void test9Demo1() { ChildInterfacd childInterfacd = new ChildInterfacd(); test9Demo(childInterfacd::method); } /** * 静态方法调用 */ @FunctionalInterface public interface Calcable{ int calc(int num); } public class Demo05Lamba implements Calcable{ @Override public int calc(int num) { return 0; } } //调用常量类 @Test public void test10() { //这个例子中,下面两种写法是等效的: //Lambda表达式: n -> Math.abs(n) //方法引用: Math::abs test10Demo(-10,n->Math.abs(n+5)); test10Demo(-10,Math::abs); } public void test10Demo(int num,Calcable c) { System.out.println(c.calc(num)); }