List fruits = new ArrayList<>();
fruits.add(new Fruit("Apple", 0.8));
fruits.add(new Fruit("orange", 0.3));
fruits.add(new Fruit("watermelon", 1.2));
fruits.add(new Fruit("banana", 0.6));
//java8之前的做法
// List tempList = new ArrayList<>();
// for(Fruit fruit : fruits){
// if(fruit.getWeight()>0.3){
// tempList.add(fruit);
// }
// }
//
// List fruitNames = new ArrayList<>();
// tempList.sort(new Comparator() {
// @Override
// public int compare(Fruit o1, Fruit o2) {
// return o1.getWeight().compareTo(o2.getWeight());
// }
// });
//
// for(Fruit fruit :tempList){
// fruitNames.add(fruit.getName());
// }
//
// System.out.println(fruitNames);
//java8的做法
List fruitName = fruits.stream().filter(f -> f.getWeight()>0.3).sorted(Comparator.comparing(Fruit::getWeight)).map((Fruit::getName)).collect(Collectors.toList());
System.out.println(fruitName);
结果:[banana, Apple, watermelon]
通过这个demo,可以很清楚地看到java8对集合的操作非常的简单并且支持对集合的链式操作,而java8之前则需要大量的迭代集合的操作代码重复很多。
需要一个数据源(如集合),一个中间操作链(过滤、排序、limit等操作),一个终端操作执行流水线并生成结果
/**
* 预定义的菜单类
*/
public class Menu {
private String name;
private double weight;
public Menu(String name, double weight) {
this.name = name;
this.weight = weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
@Override
public String toString() {
return "Menu{" +
"name='" + name + '\'' +
", weight=" + weight +
'}';
}
}
public class UsefulOperator {
public static List
结果:
[Menu{name=‘fish’, weight=1.98}, Menu{name=‘beaf’, weight=2.18}, Menu{name=‘meat’, weight=8.88}, Menu{name=‘meat’, weight=8.88}]
[Menu{name=‘fish’, weight=1.98}, Menu{name=‘apple’, weight=0.88}, Menu{name=‘beaf’, weight=2.18}, Menu{name=‘meat’, weight=8.88}, Menu{name=‘chop’, weight=0.08}]
[Menu{name=‘fish’, weight=1.98}, Menu{name=‘apple’, weight=0.88}]
[Menu{name=‘beaf’, weight=2.18}, Menu{name=‘meat’, weight=8.88}, Menu{name=‘meat’, weight=8.88}, Menu{name=‘chop’, weight=0.08}]
//映射
//map(接受一个函数并且将其映射成一个新的元素)
List newMenu5 = list.stream().map(Menu::getName).collect(Collectors.toList());
System.out.println(newMenu5);
//flatMap 可以将生成的流扁平化为单个流
List words = Lists.newArrayList("hello", "World");
//将数组words中不同单词保存下来
System.out.println(words.stream().map(word -> word.split("")).flatMap(Arrays::stream).distinct().collect(Collectors.toList()));
结果
[fish, apple, beaf, meat, meat, chop]
[h, e, l, o, W, r, d]
//判断集合中是否有任何符合条件的元素 终端操作返回boolean
if (list.stream().anyMatch(m -> m.getWeight() > 1.8)) {
System.out.println("have right fruit");
}
//判断集合的所有元素是否符合条件 终端操作返回boolean
if (list.stream().allMatch(m -> m.getWeight() > 1.8)) {
System.out.println("have all right fruit");
}
//集合中是否所有元素都不匹配指定的条件 终端操作返回boolean
if (list.stream().noneMatch(m -> m.getWeight() > 10)) {
System.out.println("have none right fruit");
}
//返回当前流中的任意元素
// //你可能会想,为什么会同时有findFirst和findAny呢?答案是并行。找到第一个元素
// //在并行上限制更多。如果你不关心返回的元素是哪个,请使用findAny,因为它在使用并行流
// //时限制较少。
Optional anyMenu = list.stream().findAny();
System.out.println(anyMenu.toString());
//返回当前流中第一个元素
Optional firstMenu = list.stream().findFirst();
System.out.println(firstMenu.toString());
结果:
have right fruit
have none right fruit
Optional[Menu{name=‘fish’, weight=1.98}]
Optional[Menu{name=‘fish’, weight=1.98}]
//规约
//元素求和
List integers = Lists.newArrayList(1, 2, 3, 4, 5, 6);
//0代表初始值
int sum = integers.stream().reduce(0, Integer::sum);
//可以不指定初始值,返回值变为Optional以防止可能为空的情况
Optional sum2 = integers.stream().reduce(Integer::sum);
System.out.println(sum);
System.out.println(sum2);
//最大值和最小值
Optional max = integers.stream().reduce(Integer::max);
// Optional min = integers.stream().reduce((a,b)->a min = integers.stream().reduce(Integer::min);
System.out.println("max==="+max+" min==="+min);
//求menu中fruit的数量
Optional fruitCount = list.stream().map(c -> 1).reduce(Integer::sum);
System.out.println("fruit's count is "+ fruitCount);
结果:
21
Optional[21]
max=Optional[6] min=Optional[1]
fruit’s count is Optional[6]
//数值流
//映射到数值流
double totalWeight = list.stream().mapToDouble(Menu::getWeight).sum();
System.out.println(totalWeight);
//转换回对象流
Stream boxed = list.stream().mapToDouble(Menu::getWeight).boxed();
//默认值OptionalDouble
OptionalDouble optionalDouble = list.stream().mapToDouble(Menu::getWeight).max();
System.out.println(optionalDouble);
System.out.println(optionalDouble.orElse(99.99));
//数值范围
System.out.println(IntStream.rangeClosed(100,200).boxed().limit(10).collect(Collectors.toList()));
//生成勾股数
Stream pythagoreanTriples =
IntStream.rangeClosed(1, 100).boxed()
.flatMap(a ->
IntStream.rangeClosed(a, 100)
.filter(b -> Math.sqrt(a*a + b*b) % 1 == 0)
.mapToObj(b ->
new int[]{a, b, (int)Math.sqrt(a * a + b * b)})
);
pythagoreanTriples.limit(5)
.forEach(t ->
System.out.println(t[0] + ", " + t[1] + ", " + t[2]));
结果:
22.88
OptionalDouble[8.88]
8.88
[100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
3, 4, 5
5, 12, 13
6, 8, 10
7, 24, 25
8, 15, 17
//由值创建流
Stream stream = Stream.of(“a”, “b”, “c”, “d”, “e”);
stream.map(String::toUpperCase).forEach(System.out::println);
//获取一个空的流
Stream empty = Stream.empty();
//由数组创建流
int[] numbers = {1, 2, 3, 4, 5};
IntStream numberStream = Arrays.stream(numbers);
Long countNumber = numberStream.count();
System.out.println(countNumber);
//由文件生成流
long uniqueWords = 0;
try (Stream lines =
Files.lines(Paths.get("G:\\IdeaProject\\javase\\src\\main\\java\\Java8\\chapter3_stream\\operate\\data.txt"), Charset.defaultCharset())) {
uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" ")))
.distinct()
.count();
System.out.println("==diff words==" + uniqueWords);
} catch (IOException e) {
}
//由函数生成流:创建无限流
//根据初始值进行操作
Stream.iterate(100, n -> 100 + new Random().nextInt(100)).limit(10).forEach(System.out::println);
Stream.iterate(new int[]{0, 1}, t->new int[]{t[1],t[0]+t[1]}).limit(20).map(t->t[0]).forEach(t -> System.out.print(t+" "));
//不需要根据生成值进行后续操作
Stream.generate(()->new Random().nextInt(100)+100).limit(20).forEach(System.out::println);