最近在工作中发现了对于集合操作转换的神器,java8新特性 stream,学习了下发现有很多值得整理的用法,这里记录下。
我们先看一段demo
//Lists是Guava中的一个工具类
List nums = Lists.newArrayList(1,null,3,4,null,6);
nums.stream().filter(num -> num != null).count();
下面我们通过具体的demo 来看下实际用法吧
forEach() -->对流中的每个元素执行一些操作。 toArray() --> 将流中的元素倾倒入一个数组。 reduce() --> 通过一个二进制操作将流中的元素合并到一起。 collect() --> 将流中的元素倾倒入某些容器,eg:一个Collection或Map. min() --> 根据一个比较器找到流中元素的最小值。 max() --> 根据一个比较器找到流中元素的最大值。 count() --> 计算流中元素的数量。 anyMatch() --> 判断流中是否至少有一个元素匹配断言。这是一个短路的操作。 allMatch() --> 判断流中是否每一个元素都匹配断言。这是一个短路的操作。 noneMatch()--> 判断流中是否没有一个元素匹配断言。这是一个短路的操作。 findFirst()--> 查找流中的第一个元素。这是一个短路的操作。 findAny() --> 查找流中的任意元素,可能对某些流要比findFirst代价低。这是一个短路的操作
/**
* filter 对原始 Stream 进行某项测试,通过测试的元素被留下来生成一个新 Stream。
*/
List nums = Lists.newArrayList(1,null,3,4,null,6);
nums.stream().filter(num -> num != null).count();
/**
* reduce 是把 Stream 元素组合起来。
* 它提供一个起始值(种子),然后依照运算规则(BinaryOperator),
* 和前面 Stream 的第一个、第二个、第 n 个元素组合。
*/
// 字符串连接,concat = "ABCD"
String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat);
// 求最小值,minValue = -3.0
double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);
// 求和,sumValue = 10, 有起始值
int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);
// 求和,sumValue = 10, 无起始值
sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
// 过滤,字符串连接,concat = "ace"
concat = Stream.of("a", "B", "c", "D", "e", "F").
filter(x -> x.compareTo("Z") > 0).
reduce("", String::concat);
/**
* limit 返回 Stream 的前面 n 个元素;
* skip 则是扔掉前 n 个元素(它是由一个叫 subStream 的方法改名而来)。
*/
List persons = new ArrayList();
for (int i = 1; i <= 10000; i++) {
Person person = new Person(i,"name"+i);
persons.add(person);
}
List personList2 = persons.stream().
map(Person::getName).limit(10).skip(3).collect(Collectors.toList());
System.out.println(personList2);
//forEach 方法接收一个 Lambda 表达式,然后在 Stream 的每一个元素上执行该表达式
// Java 8
roster.stream()
.filter(p -> p.getGender() == Person.Sex.MALE)
.forEach(p -> System.out.println(p.getName()));
// Pre-Java 8
for (Person p : roster) {
if (p.getGender() == Person.Sex.MALE) {
System.out.println(p.getName());
}
}
Stream 有三个 match 方法,从语义上说
allMatch:Stream 中全部元素符合传入的 predicate,返回 true
anyMatch:Stream 中只要有一个元素符合传入的 predicate,返回 true
noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true
List persons = new ArrayList();
persons.add(new Person(1, "name" + 1, 10));
persons.add(new Person(2, "name" + 2, 21));
persons.add(new Person(3, "name" + 3, 34));
persons.add(new Person(4, "name" + 4, 6));
persons.add(new Person(5, "name" + 5, 55));
boolean isAllAdult = persons.stream().
allMatch(p -> p.getAge() > 18);
System.out.println("All are adult? " + isAllAdult);
boolean isThereAnyChild = persons.stream().
anyMatch(p -> p.getAge() < 12);
System.out.println("Any child? " + isThereAnyChild);
/**
* 对 Stream 的排序通过 sorted 进行,
* 它比数组的排序更强之处在于你可以首先对 Stream 进行各类 map、filter、limit、skip 甚至 distinct 来减少元素数量后,
* 再排序,这能帮助程序明显缩短执行时间。
*/
List persons = new ArrayList();
for (int i = 1; i <= 5; i++) {
Person person = new Person(i, "name" + i);
persons.add(person);
}
List personList2 = persons.stream().limit(2).sorted((p1, p2) -> p1.getName().compareTo(p2.getName())).collect(Collectors.toList());
System.out.println(personList2);
}
List list = IntStream.range(1, 100).boxed().collect(Collectors.toList());
Map map = list.stream().collect(Collectors.toMap(p -> p, q->q*3));
System.out.println(map);
List list = new Random().ints(-100,100).limit(250).boxed().collect(Collectors.toList());
Optional max = list.stream().reduce(Math::max);
max.ifPresent(value -> System.out.println(value));
String[] names = { "Fred Edwards", "Anna Cox", "Deborah Patterson", "Ruth Torres", "Shawn Powell",
"Rose Thompson", "Rachel Barnes", "Eugene Ramirez", "Earl Flores", "Janice Reed", "Sarah Miller",
"Patricia Kelly", "Carl Hall", "Craig Wright", "Martha Phillips", "Thomas Howard", "Steve Martinez",
"Diana Bailey", "Kathleen Hughes", "Russell Anderson", "Theresa Perry" };
Arrays.asList(names)
.stream()
.map(String::toUpperCase)
.sorted().forEach(System.out::println);
IntStream.range(0, 10).forEach(value -> System.out.println(value));
Map> collect = persons.stream().collect(Collectors.groupingBy(Person::getAge));
Double collect = persons.stream().collect(Collectors.averagingInt(Person::getAge));
参考文献:JAVA8初体验
Java 8 中的 Streams API 详解