0
0
0
1. 云栖社区>
2. 博客>
3. 正文

第二章 Stream API

developerguy 2016-09-14 18:24:00 浏览924

1         List<String> strList = Arrays.asList("zhaojigang","nana","tianya","nana");
2         Stream<String> streamList = strList.stream();//集合转为stream
3         strList = streamList.distinct().filter(str->!str.equals("tianya")).sorted(String::compareTo).collect(Collectors.toList());
4         strList.forEach(System.out::println);

• 第一行：创建数组并转为List
• 第二行：根据List创建stream
• 第三行：对该stream进行去重-->选择-->排序-->stream转为List
• 第四行：遍历该List

Arrays.asList("zhaojigang","nana","tianya","nana").stream().distinct().filter(str->!str.equals("tianya")).sorted(String::compareTo).collect(Collectors.toList()).forEach(System.out::println);

• 集合-->Stream：stream()
• 数组-->Stream：Stream.of(T t)或者Arrays.stream(T[] t)
• 任意元素-->Stream：Stream.of(T... values)
1         List<String> strList = Arrays.asList("zhaojigang","nana","tianya","nana");
2         Stream<String> streamList = strList.stream();//集合转为stream
3
4         String[] strArray = {"java","c++","c"};
5         Stream<String> streamArray = Stream.of(strArray);//数组转为Stream
6         Stream<String> streamArray2 = Arrays.stream(strArray);//数组转为Stream
7
8         Stream<String> streamPartArray = Arrays.stream(strArray, 0, 2);//转换部分数组，范围：[0,2)
9
10         Stream<String> streamSelf = Stream.of("python","basic","php");//任意元素

1、stream2array

1         Stream<String> strStream = Stream.of("java","c++","c","python");
2         Object[] objectArray = strStream.toArray();//只能返回Object[]
3         String[] strArray = strStream.toArray(String[]::new);//构造器引用（类似于方法引用）,可以返回String[]

2、stream2collection

1         List<String> strList = strStream.collect(Collectors.toList());//返回List
2         Set<String> strSet = strStream.collect(Collectors.toSet());//返回set
3         ArrayList<String> strArrayList = strStream.collect(Collectors.toCollection(ArrayList::new));//收集到指定的List集合，例如收集到ArrayList

3、将stream中的元素拼接起来（joining()、joining(",")）

1         Stream<String> strStream = Stream.of("java","c++","c","python");
2         String str = strStream.collect(Collectors.joining());//将所有字符串拼接起来，结果：javac++cpython
3         System.out.println(str);
4
5         String str2 = strStream.collect(Collectors.joining(","));//将所有字符串拼接起来，中间用","隔开，结果：java,c++,c,python
6         System.out.println(str2);

arryIds.stream().map(Object::toString).collect(Collectors.joining(","));

4、stream2map(toMap、toConcurrentMap)

1         Stream<String> strStream = Stream.of("java","c++","c","python");
2         Map<String, Integer> map1 = strStream.collect(Collectors.toMap(Function.identity(), (x)->0));
3         //Function.identity()-->返回strStream中的元素，toMap方法的我两个参数都是Function接口型的，所以第二个参数即使只放0，也不能直接写作0，可以使用如上的方式进行操作
4
5         for(String key : map1.keySet()){
6             System.out.println("key:"+key+"->"+"value:"+map1.get(key));
7         }
8         //结果
9         /*
10         key:python->value:0
11         key:c++->value:0
12         key:c->value:0
13         key:java->value:0
14          */

• toMap-->stream转为map
• Function.identity()-->返回stream中的元素

1         Stream<String> strStream = Stream.of("java","c++","c","python","java");
2         Map<String, Integer> map1 = strStream.collect(Collectors.toMap(Function.identity(), //key
3                                                                         (x)->0,             //value
4                                                                         (existingValue, newValue) -> existingValue));//如果key重复，取旧值

1         Map<String, Integer> map1 = strStream.collect(Collectors.toMap(Function.identity(), //key
2                                                                         (x)->0,             //value
3                                                                         (existingValue, newValue) -> existingValue,//如果key重复，取旧值
4                                                                         TreeMap::new));//返回TreeMap

5、groupingBy partitioningBy

1         /***************************groupingBy partitioningBy**************************/
2         Stream<Locale> localeStream = Stream.of(Locale.getAvailableLocales());
3         Map<String, List<Locale>> country2localeList = localeStream.collect(Collectors.groupingBy(Locale::getCountry));//根据国家分组，groupBy的参数是分类器
4         List<Locale> locales = country2localeList.get("CH");
5
6         Map<String, Set<Locale>> country2localeSet = localeStream.collect(Collectors.groupingBy(Locale::getCountry, Collectors.toSet()));//根据国家分组，groupBy的参数是分类器，返回set
7         Set<Locale> localeSet = country2localeSet.get("CH");
8
9         Map<Boolean, List<Locale>> country2locales = localeStream.collect(Collectors.partitioningBy(locale->locale.getLanguage().equals("en")));//分成两组，一组为true（即语言是en的），一组为false（即语言不是en的）
10         List<Locale> trueLocale = country2locales.get(true);

1         Stream<String> streamSelf = Stream.of("python","basic","php");
2         streamSelf.filter(str->str.startsWith("p")).forEach(System.out::println);

• stream也是可以foreach的，没必要一定要转化成集合再foreach

1         Predicate<String> startCondition = str->str.startsWith("p");
2         streamSelf.filter(startCondition).forEach(System.out::println);

1         Stream<String> s = Stream.of("java1","java3","java","php12");
2         Predicate<String> condition1 = str->str.length()==5;//条件1
3         Predicate<String> condition2 = str->str.startsWith("j");//条件2
4         s.filter(condition1.and(condition2)).forEach(System.out::println);//and条件

1         Stream<String> streamSelf = Stream.of("python","basic","php");
2         streamSelf.map(String::toUpperCase).forEach(System.out::println);

1         Stream<Integer> reduceStream = Stream.of(1,2,3,4,5);
2         Optional<Integer> sumOption = reduceStream.reduce((x,y)->x+y);//计算1+2+3+4+5，即对元素中的元素进行聚合计算，而map是对元素中的每一个元素分别计算（注意：如果stream为null的话，就会产生无效的结果，需要使用Optional接收）
3         //Optional<Integer> sumOption = reduceStream.reduce(Integer::sum);//计算1+2+3+4+5，即对元素中的元素进行聚合计算，而map是对元素中的每一个元素分别计算
4
5         Integer result = reduceStream.reduce(0, Integer::sum);//0为标识值，即计算：0+1+2+。。+5，如果整个stream为null，就返回标识值。
6         System.out.println(result);

• ifPresent(xxx)：存在的就执行xxx，不存在就什么都不执行
• orElse(xxx)：存在就返回存在的值，不存在就返回xxx（可以理解为是默认值）
1         Stream<String> optionalStream = Stream.of("java","python","basic");
2         Optional<String> optionValue = optionalStream.filter(str->str.startsWith("p")).findFirst();
3         optionValue.ifPresent(str->System.out.println(str));//if optionalValue为true，即str存在，则输出str，当然也可以使用如下
4         String str = optionValue.orElse("xxx");//如果optionValue为false，即不存在以p开头的字符串时，使用"xxx"来替代
5         System.out.println(str);

Optional是Java8提供的为了解决null安全问题的一个API。善用Optional可以使我们代码中很多繁琐、丑陋的设计变得十分优雅。这篇文章是建立在你对Optional的用法有一定了解的基础上的，如果你还不太了解Optional，可以先去看看相关教程，或者查阅Java文档。

使用Optional，我们就可以把下面这样的代码进行改写。

public static String getName(User u) {
if (u == null)
return "Unknown";
return u.name;
}

public static String getName(User u) {
Optional<User> user = Optional.ofNullable(u);
if (!user.isPresent())
return "Unknown";
return user.get().name;
}

public static String getName(User u) {
return Optional.ofNullable(u)
.map(user->user.name)
.orElse("Unknown");
}

public static String getChampionName(Competition comp) throws IllegalArgumentException {
if (comp != null) {
CompResult result = comp.getResult();
if (result != null) {
User champion = result.getChampion();
if (champion != null) {
return champion.getName();
}
}
}
throw new IllegalArgumentException("The value of param comp isn't available.");
}

public static String getChampionName(Competition comp) throws IllegalArgumentException {
return Optional.ofNullable(comp)
.map(c->c.getResult())
.map(r->r.getChampion())
.map(u->u.getName())
.orElseThrow(()->new IllegalArgumentException("The value of param comp isn't available."));
}

string.ifPresent(System.out::println);

Optional的魅力还不止于此，Optional还有一些神奇的用法，比如Optional可以用来检验参数的合法性。

public void setName(String name) throws IllegalArgumentException {
this.name = Optional.ofNullable(name).filter(User::isNameValid)
}

• 使用 Java8 Optional 的正确姿势 – 隔叶黄莺 Unmi Blog (https://unmi.cc/proper-ways-of-using-java8-optional/)

https://mp.weixin.qq.com/s/p_vwjlpK6GxQBk5_nSbeQA

1、limit(long size)

1         Stream<String> streamSelf = Stream.of("python","basic","php");
2         streamSelf.limit(2).forEach(System.out::println);//截取前两个

2、skip(long size)

1         Stream<String> streamSelf = Stream.of("python","basic","php");
2         streamSelf.skip(2).forEach(System.out::println);//跳过前两个

3、contact(Stream<T>,Stream<T>)

1         Stream<String> streamSelf = Stream.of("python","basic","php");
2         Stream<String> streamSelf2 = Stream.of("python2","basic2","php2");
3         Stream.concat(streamSelf, streamSelf2).forEach(System.out::println);

1         Stream<String> streamSelf = Stream.of("python","basic","php","b");
2         System.out.println(streamSelf.count());//计算流中的元素个数
3         Optional<String> largest = streamSelf.max(String::compareToIgnoreCase);//寻找最大值
4         if(largest.isPresent()){
5             System.out.println(largest.get());
6         }

1         Optional<String> firstMatch = streamSelf.filter(str->str.startsWith("b")).findFirst();//寻找第一个符合条件的元素
2         firstMatch.ifPresent(System.out::println);//这是Optional的第一种用法
3
4         Optional<String> anyMatch = streamSelf.parallel().filter(str->str.startsWith("b")).findAny();//返回集合中符合条件的任意一个元素，对于并行处理非常好（因为多个线程只要有一个线程找到了，整个计算就会结束）
5         if(anyMatch.isPresent()){
6             System.out.println(anyMatch.get());//这里的结果可能是b,有可能是basic
7         }
8
9         boolean isAnyMatch = streamSelf.parallel().anyMatch(str->str.startsWith("c"));//集合中是否有一个满足条件
10         System.out.println(isAnyMatch);
11
12         Stream<String> streamSelf3 = Stream.of("basic","b");
13         boolean isAllMatch = streamSelf3.parallel().allMatch(str->str.startsWith("b"));//集合中是否所有元素都满足条件
14         System.out.println(isAllMatch);
15
16         boolean isAllNotMatch = streamSelf.parallel().noneMatch(str->str.startsWith("p"));//集合中是否没有一个元素满足条件
17         System.out.println(isAllNotMatch);

• optional的最佳用法：ifPresent()-->如果有就输出，如果没有，什么都不做
• parallel()：将stream转为并行流，并行流的使用一定要注意线程安全

• IntStream：int、short、char、byte、boolean
• LongStream：long
• DoubleStream：double、float

http://www.cnblogs.com/java-zhao/p/5492122.html

developerguy
+ 关注