一. 基本概念
1.1 为什么加入 集合的流式操作
JDK8 的Stream 是一个受到
函数式编程
和 多核时代影响而产生的东西。很多时候我们需要到底层返回数据,上层再对数据进行遍历,进行一些数据统计,但是之前的Java API 中很少有这种方法,这就需要我们自己来 Iterator 来遍历,如果JDK 能够为我们提供一些这种方法,并且能够为我们优化就好了。 所以JDK8加入 了 java.util.stream包,实现了集合的流式操作,流式操作包括集合的过滤,排序,映射等功能。根据流的操作性,又可以分为 串行流 和 并行流。根据操作返回的结果不同,流式操作又分为中间操作和最终操作。大大方便了我们对于集合的操作。
- 最终操作:返回一特定类型的结果。
- 中间操作:返回流本身。
1.2 什么是 流
Stream 不是 集合元素,也不是数据结构,它相当于一个 高级版本的 Iterator,不可以重复遍历里面的数据,像水一样,流过了就一去不复返。它和普通的 Iterator 不同的是,它可以并行遍历,普通的 Iterator 只能是串行,在一个线程中执行。
二. 串行流和并行流:
串行流操作在一个线程中依次完成。并行流在多个线程中完成,主要利用了 JDK7 的 Fork/Join 框架来拆分任务和加速处理。相比串行流,并行流可以很大程度提高程序的效率。
三. 中间操作 和 最终操作
中间操作:
- filter(): 对元素进行过滤
- sorted():对元素排序
- map():元素映射
- distinct():去除重复的元素
最终操作:
- forEach():遍历每个元素。
- reduce():把Stream 元素组合起来。例如,字符串拼接,数值的 sum,min,max ,average 都是特殊的 reduce。
- collect():返回一个新的集合。
- min():找到最小值。
- max():找到最大值。
实体类
/**
* 描述:菜肴
* Created by 002267 on 2017/9/7.
*/
public class Dish {
private final String name;
private final boolean vegetarian;//素食者
private final int calories;//卡路里
private final Type type;
public Dish(String name, boolean vegetarian, int calories, Type type) {
this.name = name;
this.vegetarian = vegetarian;
this.calories = calories;
this.type = type;
}
public String getName() {
return name;
}
public boolean isVegetarian() {
return vegetarian;
}
public int getCalories() {
return calories;
}
public Type getType() {
return type;
}
public enum Type {
MEAT, FISH, OTHER
}
public String toString() {
return this.name;
}
public Calories getCaloricLevel() {
if (this.getCalories() <= 300)
return Calories.DIET;
else if (this.getCalories() <= 500)
return Calories.NORMAL;
return Calories.FAT;
}
}
测试类
package java8test.dish;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.function.UnaryOperator;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.*;
/**
* 描述:
* Created by 002267 on 2017/9/7.
*/
public class DishTest {
public static boolean isNumberOrdec(String str) {
return Pattern.matches("^\\d+(\\.\\d+)?$", str);
}
static List<Dish> menu = Arrays.asList(new Dish("pork", false, 210, Dish.Type.MEAT), new Dish("beef", true, 100, Dish.Type.MEAT), new Dish("chicken", false, 440, Dish.Type.MEAT), new Dish("fries", true, 660, Dish.Type.OTHER), new Dish("rice", true, 40, Dish.Type.OTHER), new Dish("fruit", true, 110, Dish.Type.OTHER), new Dish("pizza", true, 220, Dish.Type.OTHER), new Dish("prawns", true, 50, Dish.Type.FISH), new Dish("salmon", true, 80, Dish.Type.FISH));
public enum Calories {
DIET, NORMAL, FAT
}
public static void main(String[] args) throws NoSuchAlgorithmException {
System.out.println("zZZ".matches("^[a-z]+$"));
System.out.println(Pattern.matches("[a-z]+", "zzz"));
UnaryOperator<String> head = (String text) -> "from chinese" + text;
UnaryOperator<String> spel = (String text) -> text.replaceAll("labda", "lambda");
//Function<String,String> pipel = head.andThen(spel);
//String result = pipel.apply("");
Map<String, Object> mappp = new HashMap<>();
mappp.put("name","name");
mappp.put("nick",null);
mappp.put("id","id");
System.out.println("昵称是" + (String)mappp.get("nick"));
String nick = (String)mappp.get("nick")!=null?(String)mappp.get("nick"):"";
System.out.println("昵称" + nick);
int tatalCarlories = menu.stream().collect(reducing(0, Dish::getCalories, Integer::sum));
Optional tatalCarlories1 = menu.stream().map(Dish::getCalories).reduce(Integer::sum);
System.out.println(tatalCarlories1.orElse(0));
Map<Dish.Type, Map<Calories, List<Dish>>> map = menu.stream().collect(groupingBy(Dish::getType, groupingBy(dish -> {
if (dish.getCalories() <= 300)
return Calories.DIET;
else if (dish.getCalories() <= 500)
return Calories.NORMAL;
else
return Calories.FAT;
})));
System.out.println(map);
int totalCalorries = menu.stream().collect(summingInt(Dish::getCalories));
System.out.println(totalCalorries);
List<Dish> vegetarianDishes = menu.stream().filter(d -> d.isVegetarian() == false).collect(Collectors.toList());
System.out.println(vegetarianDishes);
String shortMenu = menu.stream().map(Dish::getName).collect(joining());
String shortMenu1 = menu.stream().map(Dish::getName).collect(joining(", "));
System.out.println(shortMenu1);
/*//根据区间[x,y)求所有的三元数
Stream<int[]> threes = IntStream.rangeClosed(1, 30).boxed().flatMap(a -> IntStream.rangeClosed(a, 30).filter(b -> Math.sqrt(a * a + b * b) % 1 == 0).mapToObj(b -> new int[] { a, b, (int) Math.sqrt(a * a + b * b) }));
threes.limit(3).forEach(t -> System.out.println(t[0] + "," + t[1] + "," + t[2]));
List<String> names = menu.stream()//获得流
.filter(d -> d.getCalories() > 300)//中间操作
.map(Dish::getName)//中间操作
.limit(3)//中间操作
.collect(Collectors.toList());//将stream转换为List
List<Dish> lowCaloricDishes = new ArrayList<>();
for (Dish d : menu) {
if (d.getCalories() < 300) {
lowCaloricDishes.add(d);
}
}
Collections.sort(lowCaloricDishes, new Comparator<Dish>() {
@Override
public int compare(Dish o1, Dish o2) {
return Integer.compare(o1.getCalories(), o2.getCalories());
}
});
List<String> lowCaloricDishesName = new ArrayList<>();
for (Dish d : lowCaloricDishes) {//显式顺序迭代菜单列表
lowCaloricDishesName.add(d.getName());//提取名称并将其添加到累加器
}*/
/*List<String> highCaloriesName = menu.stream().filter(d -> d.getCalories() > 200).map(Dish::getName).limit(3).collect(Collectors.toList());
System.out.println(highCaloriesName);
Map<String, Object> objectMap = new HashMap<>();
objectMap.put("a", "abc");
objectMap.put("b", "bcd");
objectMap.put("c", "def");
Set<Map.Entry<String, Object>> s = objectMap.entrySet();
Map<String, String> map = objectMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> (String) e.getValue()));
List<Dish> dishes = menu.stream().filter(d -> d.getType() == Dish.Type.MEAT).limit(2).collect(Collectors.toList());
List<Integer> dishs = menu.stream().map(Dish::getName).map(String::length).collect(Collectors.toList());
System.out.println(dishs);
menu.stream().filter(Dish::isVegetarian).findAny().ifPresent(d -> System.out.println(d.getName()));
List<Integer> numbers = Arrays.asList(1, 2, 3);
int sum = numbers.stream().reduce(0, Integer::min);
System.out.println(sum);
Optional<Integer> sum1 = numbers.stream().reduce((a, b) -> (a + b));
System.out.println(sum1);
int count = menu.stream().map(d -> 1).reduce(0, (a, b) -> a + b);
System.out.println(menu.stream().count());
System.out.println(count);
System.out.println(menu.stream().mapToInt(Dish::getCalories).sum());
Stream<Integer> integerStream = menu.stream().mapToInt(Dish::getCalories).boxed();*/
}
}
标签:String,stream,menu,System,流式,println,Dish,操作,Java8
From: https://blog.51cto.com/u_11906056/6984939