码迷,mamicode.com
首页 > 编程语言 > 详细

Java8 第五章

时间:2017-10-29 13:47:27      阅读:272      评论:0      收藏:0      [点我收藏+]

标签:integer   identity   分类   lock   avg   atom   创建   执行   dem   

如果limit用在无序流比如源是Set会出现什么??

GEOHASH??

Stream勾股数??

flatMap还是不是很明白

 

git merge master --allow-unrelated-histories
这个指令,可以强制把 无关联的分支,merge过来?????

 

 

 

筛选和切片

-- filter ==> 接受一个谓词(一个返回boolean的函数)作为参数,并返回一个包括符合谓词的元素的流.

-- distinct ==> 返回一个元素各异(根据流所生成元素的hashCode和equals方法实现)的流.

                ==> 就是去重说的那么费劲.

 
List<Integer> numbers = Arrays.asList(1,2,1,3,3,2,4);
        numbers.stream().filter(i->i % 2 ==0)
                .distinct()
                .forEach(System.out::println);
输出:
2
4
 
 
-- 上面的numbers ==> 数值流(Stream<Integer>)

 

-- limit ( n ) ==> 返回一个不超过给定长度的流,如果流有序,则最多返回前n个元素.

--flatmap ==> (扁平化)方法让你把一个流中的每个值都转换成流,然后把所有的流连接起来成为一个流 .

--skip() ==>返回扔掉了前n个元素的流.

List<Dish> dishes = menu.stream().filter(d->d.getCalories()>300).skip(2).collect(toList()); //skip()
List<Dish> noSkipDishes = menu.stream().filter(d->d.getCalories()>300).collect(toList());   //谓词筛选
List<Dish> firstSkipDish = menu.stream().skip(2).collect(toList());                         //skip
List<Integer> map = menu.stream().map(Dish::getName).map(String::length).collect(toList());//对流中的每一个元素应用函数
 
 
 

小例子:

 

-- 给定列表[1,2,3] 和列表[3,4],返回 [(1,3),(1,4),(2,3),(2,4),(3,3),(3,4)]
List<Integer> numbers1 = Arrays.asList(1,2,3);
List<Integer> numbers2 = Arrays.asList(3,4);
List<int []> pairs = numbers1.stream.flatmap(i -> numbers2.stream
                            .map(j -> new int[]{i,j})).collect(toList());
-- 拓展前一个例子,只返回综合能被三整除的数对.
List<Integer> numbers1 = Arrays.asList(1,2,3);
List<Integer> numbers2 = Arrays.asList(3,4);
List<int []> pairs = numbers1.stream.flatmap(i -> numbers2.stream
                         .filter(j -> (i+j) % 3 == 0) 
                             .map(j -> new int[]{i,j})).collect(toList());
//numbers1.stream().flatMap(i -> numbers2.stream()
.map(jj -> Arrays.toString(new int[]{ i, jj }))).forEach(System.out::println);
 
 
-- anyMatch==>流中是否有一个元素能够匹配给定的谓词,返回boolean,是一个终端操作.
-- allMatch ==>流中是否所有元素都能够匹配给定的谓词,返回boolean,是一个终端操作 .
-- noneMatch ==>流中没有任何元素与给定的谓词匹配,返回boolean,是一个终端操作.

 

-- anyMatch allMatch和noneMatch这三个操作都用到了我们所谓的短路,这就是Java中&&和||运算符在流中的版本。 

-- 短路==>操作不需要处理整个流就能得到结果,就像用and连接的大布尔表达式求值,不管表达式多长,

                主要找到 一个表达式是false整个表达式就返回false.

-- findAny==>返回当前流中的任意元素.终端操作.可以配合其他流操作使用.

 

Optional<Dish> any = menu.stream().filter(x -> x.getCalories() > 300).findAny();
为什么返回Optional?
Optional<T>类是一个容器类,代表一个值存在或者不存在.在上面的例子中findAny可能什么元素都没找到.
Optional中显式的检查值是否存在方法==>
isPresent( ) 将在Optional包含值的时候返回true,否则返回false.
ifPresent( Comsumer<T> block) 会在值存在的时候执行给定的代码块.
T get() 会在值存在的时候返回值,否则抛出NoSuchElement异常
T orElse(T  other) 会在值存在的时候返回值,否则返回默认值.  
 
 
-- findFirst()==>返回流中第一个元素
总结:
到目前为止所有的终端操作
  • 返回一个boolean(allMatch之类)
  • 返回void的(foreach等)
  • 返回Optional对象(findAny等)

 

 

规约

 

 
reduce==>
  • 有初始值  : 一个是初始值,一个是BinaryOperator<T>将两个元素结合起来产生一个新值.
  • 无初始值  : 无初始值时,因为有可能没有元素为null嘛,所以设计的时候返回值为Optional<T>对象.
Optional<Integer> sum = numbers1.stream().reduce(Integer::sum);   //无初始值
Integer sum1 = numbers1.stream().reduce(0, Integer::sum); //有初始值
Optional<Integer> max1 = numbers1.stream().reduce(Integer::max);  //无初始值
Integer max2 = numbers1.stream().reduce(0, Integer::max); //有初始值
Optional<Integer> min1 = numbers1.stream().reduce(Integer::min);  //无初始值
Integer min2 = numbers1.stream().reduce(0, Integer::min); //有初始值
 
//计算menu中一共多少个菜
int count = menu.stream().map(x->1).reduce(0,Integer::sum);
long count1 = (long) menu.size();
long count2 =  menu.stream().count();
 
 
数值流

 

--原始类型特化==>防止来回装箱和拆箱

--映射到数值流<==>转换回对象流 

 

  • 将流转换成特化版本 : mapToInt , mapToDouble , mapToLong.
int calories = menu.stream().          //返回一个Stream<Dish>
       mapToInt(Dish::getCalories)    //返回一个IntStream
          .sum();                  //
IntStream intStream = menu.stream().mapToInt(Dish::getCalories); //将Stream转换为数值流
java.util.stream.Stream<Integer> stream1 = intStream.boxed();  //将数值流转换成一般流(装箱操作)
 
 
-- 默认值OptionalInt
OptionalInt max = menu.stream().mapToInt(Dish::getCalories).max();
int max4 = max.orElse(1);   //如果没有最大值,显式提供一个默认的最大值.
 
 
-- 数值范围
range和rangeClose的区别==>range不包含结束值 
List<Integer> collect = IntStream.rangeClosed(1, 100).filter(n -> n % 2 == 0)  //一个从1到100的偶数流    
                            .boxed()                                        //数值流转化成一般流
                                    .collect(Collectors.toList());                  //转化成list
 
 
-- 创建流
//创建流
//创建数组流
 int[] numbers3 ={2,3,4,5,6,11,13};
 int sum3 = Arrays.stream(numbers3).sum();
 //由值创建流
 Stream<String> stream22 = Stream.of("Java8","Lambda","In");
stream22.map(String::toUpperCase).forEach(System.out::println);
//由文件生成流 省略
System.out.println("-----------------------------------");
//创建无限流(一般在生成一系列值的时候应该使用iterate)
 Stream.iterate(0,n->n+2).limit(10).forEach(System.out::println);
 
 
汇总
--查找流中的最大值(两种情况)
//一个是值一个是对象,不一样!
OptionalInt intStream1 = menu.stream().mapToInt(Dish::getCalories).max();//返回对象的热量最大的那个值
Optional<Dish> collect1 = menu.stream().collect(maxBy(Comparator.comparing(Dish::getCalories)));//返回热量最大的那个对象
自动提示转换==>
Optional<Dish> max3 = menu.stream().max(Comparator.comparing(Dish::getCalories));//返回热量最大的那个对象
 
 
--求和
 
Integer ccollect2 = menu.stream().mapToInt(Dish::getCalories).sum();
Integer collect2 = menu.stream().collect(summingInt(Dish::getCalories));
 
 
--求平均值
 
double avgCalories = menu.stream().collect(averagingInt(Dish::getCalories));
 
 
--通过工厂类(summarizingInt)
 
IntSummaryStatistics collect3 = menu.stream().collect(summarizingInt(Dish::getCalories));
double average = collect3.getAverage();
long count3 = collect3.getCount();
int max5 = collect3.getMax();
int min = collect3.getMin();
long sum2 = collect3.getSum();
 
 
-- 连接字符串
 
<wiz_code_mirror>
 
 
 
 
 
String collect4 = menu.stream().map(Dish::getName).collect(joining(","));
System.out.println(collect4);
输出:
pork,beef,chicken,french fries,rice,season fruit,pizza,prawns,salmon
 
 
-- 分组
 
//一级分组(普通的groupingBy(f)<=实际是=>groupingBy(f,toList()))
Map<Dish.Type, List<Dish>> collect5 = menu.stream().collect(groupingBy(Dish::getType));
//一级分组
Map<CaloricLevel, List<Dish>> collect6 = menu.stream().collect(groupingBy(x -> {
   if (x.getCalories() <= 400) return CaloricLevel.DIET;
   else if (x.getCalories() <= 700) return CaloricLevel.NORMAL;
    else return CaloricLevel.FAT;
}));
//二级分组
menu.stream().collect(groupingBy(Dish::getType, groupingBy(dish -> {
  if (dish.getCalories() <= 300) return CaloricLevel.DIET;
  else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
  else return CaloricLevel.FAT;
})));
输出:
{
  MEAT={DIET=[chicken], NORMAL=[beef], FAT=[pork]}, 
  FISH={DIET=[prawns], NORMAL=[salmon]},
  OTHER={DIET=[rice, seasonal fruit], NORMAL=[french fries, pizza]}
} 
?
?
//传递counting收集器作为groupingBy收集器的第二个参数
//collect7==> {MEAT=3, FISH=2, OTHER=4}
Map<Dish.Type, Long> collect7 = menu.stream().collect(groupingBy(Dish::getType, counting()));
//以Dish的类型作为键 ,以包装了该类型中热量最高的Dish的Optional<Dish>作为值,Optional没有实际意义其实
//collect8==> {FISH=Optional[salmon], OTHER=Optional[pizza], MEAT=Optional[pork]}
Map<Dish.Type, Optional<Dish>> collect8 = menu.stream().collect(groupingBy(Dish::getType,
        maxBy(Comparator.comparingInt(Dish::getCalories))));
//把收集器的结果转换为另一种类型,使用Collectors.collectingAndThen工厂方法返回的收集器.
//这个工厂方法接受两个参数——要转换的收集器以及转换函数,返回另一个收集器.
//collect9 ==>  {FISH=salmon, OTHER=pizza, MEAT=pork}
Map<Dish.Type, Dish> collect10 = menu.stream().collect(groupingBy(Dish::getType,
        collectingAndThen(maxBy(Comparator.comparingInt(Dish::getCalories)), Optional::get)));
?
Map<Dish.Type, Dish> collect9 = menu.stream().collect(Collectors.toMap(Dish::getType,
        Function.identity(),
        BinaryOperator.maxBy(Comparator.comparingInt(Dish::getCalories))));
?
Map<Dish.Type, IntSummaryStatistics> collect11 = menu.stream()
        .collect(groupingBy(Dish::getType,
        summarizingInt(Dish::getCalories)));
?
//groupingBy()和map()收集器搭配使用
//collect12==>{OTHER=[DIET, NORMAL], MEAT=[DIET, NORMAL, FAT], FISH=[DIET, NORMAL]}
Map<Dish.Type, Set<CaloricLevel>> collect12 =
        menu.stream().collect(
                groupingBy(Dish::getType, mapping(
                        dish -> { if (dish.getCalories() <= 400) return CaloricLevel.DIET;
                        else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
                        else return CaloricLevel.FAT; },toCollection(HashSet::new))));    
Map<Dish.Type, Set<CaloricLevel>> collect12 =
        menu.stream().collect(
                groupingBy(Dish::getType, mapping(
                        dish -> { if (dish.getCalories() <= 400) return CaloricLevel.DIET;
                        else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
                        else return CaloricLevel.FAT; },toSet())));   
 
 
-- 分区
 
 //分区是分组的特殊情况: 由一个谓词(返回一个布尔值)作为分类函数==>称之为分区函数
 //分区函数返回一个布尔值,意味着分组的Map的键类型是Boolean==>因此最多分两组,true一组,false一组
  //关键字:partitionBy 分区
  //collect13
  Map<Boolean, List<Dish>> collect13 = menu.stream().collect(partitioningBy(Dish::isVegetarian));
  List<Dish> dishes1 = collect13.get(true);//找出所有素菜
  

Java8 第五章

标签:integer   identity   分类   lock   avg   atom   创建   执行   dem   

原文地址:http://www.cnblogs.com/nzhbk/p/7749742.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!