在学习Stream Api 必须要了解 Lambda 表达式的使用,因为Stream是建立在Lambda上面
一 : Lambda四大核心接口,也叫函数式接口
/** * java8四大核心函数式接口 * Consumer<T> :消费接口 * void accept(T t); * * * Suppliter<T>:供给型接口 * T get(); * * * Function<T,R>:函数型接口 * R apply(T t); * * * Predicate<T> : 断言型接口 * boolean test(T t); */
/** * Consumer<T> :消费接口 */ @Test public void test1() { happy( 100,(x) -> System.out.println("消费"+x)); } public void happy(double d, Consumer<Double> consumer) { consumer.accept( d ); } /** *Suppliter<T>:供给型接口 */ @Test public void test2() { List <Integer> i = getLsut(10,() -> (int)Math.random()*100); i.forEach( (o) -> System.out.println(o)); } /** * 得到任意长度的集合 * @param i * @param supplier * @return */ public List<Integer> getLsut(int i, Supplier<Integer> supplier) { List<Integer> list = new ArrayList <>( ); for(int j = 0;i<=i;++j) { Integer integer = supplier.get(); list.add( integer ); } return list; } /** *Function<T,R>:函数型接口 */ @Test public void test3() { getString( "sdfds ",(x1) -> x1.trim() ); } /** * 去掉字符串中的空格 * @param s * @param function * @return */ public String getString(String s, Function<String,String> function) { return function.apply( s ); } /** *Predicate<T> : 断言型接口 */ @Test public void test4() { List<String> sli = Arrays.asList( "dddd","fgg","gfjjg","fsdfsgdf" ); List<String> list = checkString(sli,(s) -> s.length()>5); list.forEach( (s) -> System.out.println(s)); } /** * 将满足条件的数据放在集合中 */ public List<String> checkString(List<String> list, Predicate<String> predicate) { List<String> slist = new ArrayList <>( ); list.forEach( (o) -> { if(predicate.test( o )) { slist.add( o ); } } ); return slist;
二: 方法的引用形式
** * 方法引用: * 若Lambda体中的的内容有方法以及实现了,我们就可以使用“方法引用” * (可以理解为方法引用是Lambda表达式的另外一种表现形式) * * 方法格式: * 对象::实例方法名 * * 类::静态方法名 * * 类::实例方法名 * *
@Test public void test1() { haap( 12,(x) -> System.out.println(x+1)); } public void haap(double d,Consumer<Double> consumer) { consumer.accept( d ); } /** * 对象::实例方法名 */ public void test2() { Consumer<Double> consumer = (x) -> System.out.println("ss"+x); /** * 要使用方法引用是使 实现的方法返回值类型和参数类型和执行的方法返回值和参数类型一样 */ Consumer<Double> consumer1 = System.out::print; } @Test public void test3() { Use u = new Use( "Sd",1,2 ); Supplier<String> s = () -> u.getName(); s.get(); Supplier<String> ss = u::getName; } /** * 类::静态方法名 */ public void test4() { Comparator<Integer> comparable = (x, y) -> Integer.compare(x,y); Comparator<Integer> c = Integer::compare; } /** * 类::实例方法名 */ public void test5() { //参数列表的第一个参数是实例方法的调用者,第二个参数是实例方法的参数。 BiPredicate<String,String> bb = (x,y) -> x.equals( y ); BiPredicate<String,String> b = String::equals; } /** * 构造器引用 * * */ public void test6() { Supplier<Use> ss = () -> new Use( "s",1,2 ); ss.get(); //构造器引用 调用无参的构造器 Supplier<Use> s = Use::new; s.get(); } /** * 数组引用 */ @Test public void test7() { Function<Integer,String[]> ff = (x) -> new String[x]; Function<Integer,String[]> f = String[]::new; String[] s = f.apply( 20 ); System.out.println(s.length); }
3:Stream的使用
package com.example.jedis.test; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.*; import java.util.stream.Stream; /** * ***GOOD LUCK**** * * @Author : Wukn * @Date : 2018/6/ */ /** * StreamApi * * */ @SpringBootTest @RunWith(SpringRunner.class) public class StreamApiDemo { /** * Stream三个操作步骤 * 1,创建Stream * 2,中间操作 * 3,中止操作 */ /*********************************************** Stream流的创建 ***************************************************************/ /** * 创建Stream流的方式 */ @Test public void test1() { /**可以通过Collection 集合系列提供的 * stream() 串行流 * 或 * parallelStream() 并行流 */ List<String> list = new ArrayList <>( ); Stream<String> stream = list.stream(); /** *通过Arrays中的静态方法stream()获取数组流 */ Use[] uses = new Use[10]; Stream<Use> stream1 = Arrays.stream( uses ); /** * 通过Stream类中的静态方法 of() */ Stream<String> stream2 = Stream.of( "aa" ); /** * 创建无限流 */ //迭代 Stream<Integer> stream3 = Stream.iterate( 0,(x) -> x+2 ); stream3.limit( 10 ).forEach( (x) -> System.out.println(x)); //生成 Stream.generate( () -> Math.random() ) //数据源,可以产生任意的随机数 .limit( 5 ) //中间操作,只需要五个随机数 .forEach( System.out::println ); //中止操作,遍历打印这五个 } /*********************************************** Stream流的中间操作 ***************************************************************/ /** * Stream流的中间操作 */ /** * 筛选与切片 * * filter - 接受Lambda,从流中排除某些元素 * limit - 截断流,使其元素不超过给定数量 * skip(n) - 跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit互补 * distinct - 筛选,通过流所生产元素的hashCode() 和 equals() 去除重复元素 */ final List<Use> list = Arrays.asList( new Use( "a",1,3 ), new Use( "e",5,4 ), new Use( "c",2,5 ), new Use( "b",4,2 ), new Use( "e",3,1 )); //内部迭代 @Test public void test2() { /** * 中间操作不会单独执行.只有执行中止操作才会去执行中间, */ //创建Stream对象 Stream stream = list.stream() //中间操作 /** filter里面是一个断言型接口,传入一个参数,返回一个boolean值 filter - 接受Lambda,从流中排除某些元素*/ .filter( (x) -> x.getId()>1); //中止操作 stream.forEach( System.out::println ); } @Test public void test4() { list.stream() .filter( (x) -> x.getSaler()>2 ) /**只需要找到满足条件之后,就不会去继续迭代其他,提高了效率, limit - 截断流,使其元素不超过给定数量*/ .limit( 2 ) .forEach( System.out::println ); } @Test public void test5() { list.stream() .filter( (x) -> x.getId()>0 ) .limit(3 ) /**skip(n) - 跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit互补*/ .skip( 2 ) .forEach( System.out::println ); } @Test public void test6() { list.stream() .filter( (x) -> x.getId()>0 ) .limit( 5 ) .skip( 2 ) /**distinct - 筛选,通过流所生产元素的hashCode() 和 equals() 去除重复元素 在使用此方式时一定要重写hashCode() 和 equals()*/ .distinct() .forEach( System.out::println ); } //外部迭代 @Test public void test3() { Iterator<Use> stream = list.iterator(); if(stream.hasNext()) { System.out.println(stream.next()); } } /** * 映射 * * map - 接收Lambda,将元素转化成其他形式或提取信息,接收一个函数作为参数,改元素会应用到每个元素上, * 并将其映射成一个新的元素, * * flatMap - 接收一个函数作为参数,将流中的的每个值都换成另一个流,然后把所有的流连接成一个流 */ @Test public void test7() { List<String> slist = Arrays.asList( "aa","bb","cc","dd","ee","ff","gg" ); slist.stream() /**map 的作用是将集合中的每个属性放在函数中去执行,执行的结果作为一个新的流,最后在中止操作中打印出来*/ .map( (x) -> x.toUpperCase() ) .forEach( System.out::println ); list.stream() .map( Use::getSaler ) .forEach( System.out::println ); // Stream<Stream<Character>> ssss = slist.stream() .map( (x) -> getString( x )); ssss.forEach( (x) ->{ x.forEach( System.out::println ); } ); } @Test public void test8() { List<String> slist2 = Arrays.asList( "aa","bb","cc","dd","ee","ff","gg" ); /**map是使一个流中,存在几个小的流,这样就形成了几个小的流.形成一个大的流,所有在遍历时先去遍历大的流.得到每个小的流后再去遍历这个小流*/ Stream<Stream<Character>> ssss = slist2.stream() .map( (x) -> getString( x )); ssss.forEach( (x) ->{ x.forEach( System.out::println ); } ); /**flatMap - 接收一个函数作为参数,将流中的的每个值都换成另一个流,然后把所有的流连接成一个流*/ Stream<Character> stream = slist2.stream() .flatMap( (x) -> getString( x ) ); stream.forEach( System.out::println ); } public static Stream<Character> getString(String str) { List<Character> sslist = new ArrayList <>( ); for(Character c:str.toCharArray()) { sslist.add( c ); } return sslist.stream(); } /** * 排序 * * sortrd - 自然排序 * * sorted(Comparator con) - 定制排序 */ @Test public void test9() { List<String> slist2 = Arrays.asList( "bb","ff","cc","dd","aa","ee","gg" ); slist2.stream() //自然排序 .sorted() .forEach( System.out::println ); list.stream() //定制排序 .sorted((x,y) -> { if(x.getId( ).equals( y.getId( ) )) { return x.getSaler().compareTo( y.getSaler() ); }else { return x.getId().compareTo( y.getId() ); }}) .forEach( System.out::println ); ; } /*************************************Stream流的中止操作******************************************************/ /** * 查找与匹配 * * allMatch - 检查是否匹配所有元素 * anyMatch - 检查是否至少匹配一个元素 * noneMatch - 检查是否没有匹配所有元素 * findFirst - 返回第一个元素+ * findAny - 返回当前流中的任意元素 * count - 返回流中元素的总和 * max - 返回流中的最大值 * min - 返回流中的最小值 */ @Test public void test10() { boolean b = list.stream() /**检查是否匹配所有元素 就是检查对象中的元素是否都满足allMatch()里面的要求,是就返回true 反之 false*/ .allMatch( (x) -> x.getId()>2 ); System.out.println(b); boolean b1 = list.stream() /**检查是否至少匹配一个元素 就是检查对象中的元素是否至少有一个满足anyMatch()里面的要求,是就返回true 反之 false*/ .allMatch( (x) -> x.getId()>0 ); System.out.println(b1); boolean b2 = list.stream() /**检查是否没有匹配所有元素 就是检查对象中的元素是否有满足noneMatch()里面的要求,是就返回true 反之 false*/ .allMatch( (x) -> x.getId()>0 ); System.out.println(b2); Optional b3 = list.stream() /**先排序*/ .sorted((x,y) -> Double.compare( y.getId(),x.getId() )) /**返回第一个元素*/ .findFirst( ); System.out.println(b3.get()); Optional optional = list.stream() .filter( (x) -> x.getId()>4 ) /**findAny - 返回当前流中的任意元素*/ .findAny(); System.out.println(optional.get()); Long l = list.stream() .filter( (x) -> x.getId()>0 ) /*** * count - 返回流中元素的总和*/ .count(); System.out.println(l); Optional optional2 = list.stream() /**max - 返回流中的最大值**/ .max( (x,y) -> Double.compare( x.getId(),y.getId() ) ); System.out.println(optional2.get()); Optional optional3 = list.stream() /**min - 返回流中的最小值**/ .max( (x,y) -> Double.compare( x.getId(),y.getId() ) ); System.out.println(optional3.get()); /** * 得到具体的最小id */ Optional<Integer> o = list.stream() //首先通过映射,得到一个id流,这个流包含所有的id .map( (x) -> x.getId() ) //从新建的流中得到 .min( (x,y) -> Double.compare( x,y ) ); System.out.println(o.get()); } }