Java8新特性
1、Stream流
Stream流的思想:
Stresm流可以看成流水线的过滤操作
Stream流的三类方法
(1).获取stream流
创建一条流水线,并把数据放到流水线上准备进行操作。
(2).中间方法
流水线上的操作
一次操作完毕之后,还可以继续进行其他操作。
(3).终结方法
一个Stream流只能有一个终结方法
是流水线上的最后一个操作
什么情况下可以使用Stream流?
(1、stream流的获取方法
单列集合
可以使用Collection接口中的默认方法stream()生成流
defalut Stream<E> stream()
集合对象.stream();
双列集合
不能直接获取,需要间接获取
可以先通过keySet或者entrySet获取一个Set集合,再获取Stream流
集合对象.keySet().stream();
集合对象.entrySet().stream();
数组
Arrays中的静态方法stream生成流
Arrays.stream(数组名);
同种数据类型的多个数据
1,2,3,4,5,6..
"aaa","bbb","ccc","ddd","eee"...
使用Stream.of(T...values)生成流
Stream.of(数据1,数据2,数据3...);
import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Set; import java.util.stream.Stream; public class MyStream2 { public static void main(String[] args) { /* stream流的获取: 单列集合:集合对象.stream(); 双列集合:不能直接获取,需要间接获取 集合对象.keySet().stream(); 集合对象.entrySet().stream(); 数组 :Arrays.stream(数组名) 同种数据类型的多个数据: Stream.of(数据1,数据2,数据3...); */ //单列集合 //methd1(); //双列集合 //method2(); //数组 //method3(); //同种数据类型的多个数据 //method4(); } private static void method4() { Stream.of(1,2,3,4,5,6).forEach(s-> System.out.println(s)); } private static void method3() { int [] arr = {1,2,3,4,5}; Arrays.stream(arr).forEach(s-> System.out.println(s)); } private static void method2() { HashMap<String,Integer> hm = new HashMap<>(); hm.put("zzhangsan",23); hm.put("lisi",24); hm.put("wangwu",25); hm.put("zhaoliu",26); hm.put("xiaoqi",27); /*//注意;双列集合不能直接获取stream流 //keySet //先获取到所有的键 //再把这个集合中所有的键放到stream流中 hm.keySet().stream().forEach(s-> System.out.println(s));*/ //使用entryset //先获取到所有的键值对对象 //再把这个set集合中所有的键值对对象放到stream流中 hm.entrySet().stream().forEach(s-> System.out.println(s)); } private static void methd1() { ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); /* Stream<String> stream = list.stream(); stream.forEach(s-> System.out.println(s));*/ list.stream().forEach(s-> System.out.println(s)); } }
(2、Stream流的常见中间操作方法
import java.util.ArrayList; import java.util.function.Predicate; public class MyStream3 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("张三丰"); list.add("张无忌"); list.add("张翠山"); list.add("王二麻子"); list.add("张良"); list.add("谢广坤"); //list.stream().filter( //filter方法获取流中的每一个数据 //而test方法中的s,就一次表示流中的每一个数据 //我们只需要在test方法中对s进行判断就可以了 //如果判断的结果为true,那么当前的数据就留下 //如果为false,则当前数据就不要了 /* new Predicate<String>() { @Override public boolean test(String s) { boolean result = s.startsWith("张"); return result; } } ).forEach(s-> System.out.println(s));*/ //因为predicate接口中只要一个抽象方法test //所以我们可以用lambda表达式进行简化 /* list.stream().filter( (String s)->{ boolean result = s.startsWith("张"); return result; } ).forEach(s-> System.out.println(s));*/ list.stream().filter(s->s.startsWith("张")).forEach(s-> System.out.println(s)); } }
import java.util.ArrayList; import java.util.stream.Stream; public class MyStream4 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("张三丰"); list.add("张无忌"); list.add("张翠山"); list.add("王二麻子"); list.add("张良"); list.add("谢广坤"); list.add("谢广坤"); list.add("谢广坤"); list.add("谢广坤"); list.add("谢广坤"); //Stresm<T> limit (long maxSize)截取指定参数个数的数据 //method1(list); //Stream(T) skip (long n):跳过指定参数个数的数据 //method2(list); //static <T> concat (Stream a, stream b);合并a和b两个流为一个流 //method3(list); //Stream<T> distinct ():去除流中·重复的元素 list.stream().distinct().forEach(s-> System.out.println(s)); } private static void method3(ArrayList<String> list) { ArrayList<String> list2 = new ArrayList<>(); list2.add("张三丰"); list2.add("张无忌"); list2.add("张翠山"); list2.add("王二麻子"); list2.add("张良"); list2.add("谢广坤"); /* Stream<String> stream1 = list.stream(); Stream<String> stream2 = list2.stream(); Stream<String> stream3 = Stream.concat(stream1, stream2); stream3.forEach(s-> System.out.println(s));*/ Stream.concat(list.stream(),list2.stream()).forEach(s-> System.out.println(s)); } private static void method2(ArrayList<String> list) { //去除前面的,留下后面的 list.stream().skip(2).forEach(s-> System.out.println(s));//张翠山 王二麻子 张良 谢广坤 } private static void method1(ArrayList<String> list) { //list.stream().limit(2).forEach(s-> System.out.println(s));//张三丰 张无忌 list.stream().limit(4).forEach(s-> System.out.print(s));//张三丰 张无忌 张翠山 王二麻子 } }
(3、常见的终端方法
import java.util.ArrayList; import java.util.function.Consumer; public class MyStream5 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("张三丰"); list.add("张无忌"); list.add("张翠山"); list.add("王二麻子"); list.add("张良"); list.add("谢广坤"); //void forEach(consumer action):对此流的每一个数据进行操作 //Consumer中的方法 void accept(T t):对给定的参数执行此操作 //在forEach方法的底层,会循环获取到流中的每一个数据 //并循环调用accept方法并把每一个数据传递给accept方法 //s就一次表示了流中的每一个数据 //所以,我们只要在accept方法中写上处理的业务逻辑即可 /*list.stream().forEach( new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } } );*/ list.stream().forEach(s-> System.out.println(s)); //long count():返回次流中的元素数 long count = list.stream().count(); System.out.println(count); } }
import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; public class MyStream7 { public static void main(String[] args) { ArrayList<Integer> list1 = new ArrayList<>(); for (int i = 1; i <= 10; i++) { list1.add(i); } list1.add(10); list1.add(10); list1.add(10); list1.add(10); list1.add(10); //filter负责过滤数据的 //collect负责收集数据的 //获取流中剩余的数据,不负责创建容器,也不负责把数据添加·到容器中 //Collectors.toList():在底层会创建一个list集合,并把索引数据添加到list集合中 // List<Integer> list = list1.stream().filter(number -> number % 2 == 0) .collect(Collectors.toList()); System.out.println(list); Set<Integer> set = list1.stream().filter(number -> number % 2 == 0) .collect(Collectors.toSet()); System.out.println(set); //list和set的区别 //在于去重复 } }
import java.util.ArrayList; import java.util.function.Consumer; public class MyStream5 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("张三丰"); list.add("张无忌"); list.add("张翠山"); list.add("王二麻子"); list.add("张良"); list.add("谢广坤"); //void forEach(consumer action):对此流的每一个数据进行操作 //Consumer中的方法 void accept(T t):对给定的参数执行此操作 //在forEach方法的底层,会循环获取到流中的每一个数据 //并循环调用accept方法并把每一个数据传递给accept方法 //s就一次表示了流中的每一个数据 //所以,我们只要在accept方法中写上处理的业务逻辑即可 /*list.stream().forEach( new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } } );*/ list.stream().forEach(s-> System.out.println(s)); //long count():返回次流中的元素数 long count = list.stream().count(); System.out.println(count); } }