java8学习笔记(1)
1.Lambda表达式
- 一个 Lambda 表达式可以有零个或多个参数。
- 参数的类型既可以明确声明,也可以根据上下文来推断。
- 所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (String a, int b, float c)
- 空圆括号代表参数集为空。例如:() -> 42
- 当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> a*a
- 如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致
- Lambda的变量捕获,与匿名内部类一样也是不能捕获发生改变的,如果发生改变就会报错。
2.Stream流
流的操作类型分为两种:
-
Intermediate:一个流可以后面跟随零个或多个intermediate操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。这类操作都是惰性化的(lazy),就是说,仅仅调用到这类方法,并没有真正开始流的遍历
map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered -
Terminal:一个流只能有一个terminal操作,当这个操作执行后,流就被使用“光”了,无法再被操作。所以,这必定是流的最后一个操作。Terminal操作的执行,才会真正开始流的遍历,并且会生成一个结果,或者一个side effect。
forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator -
转换操作都是lazy的,多个转换操作只会在Terminal操作的时候融合起来,一次循环完成。我们可以这样简单的理解,Stream里有个操作函数的集合,每次转换操作就是把转换函数放入这个集合中,在Terminal 操作的时候循环Stream对应的集合,然后对每个元素执行所有的函数。
-
short-circuiting操作。用以指:对于一个intermediate操作,如果它接受的是一个无限大(infinite/unbounded)的Stream,但返回一个有限的新Stream;对于一个terminal操作,如果它接受的是一个无限大的Stream,但能在有限的时间计算出结果。
anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit
1.创建流
- 单列集合
通过 java.util.Collection.stream() 方法
List<String> list = Arrays.asList("hello","world","stream");
//创建顺序流
Stream<String> stream = list.stream();
- 数组
- Arrays.stream(T[] array)方法
String[] array = {"h", "e", "l", "l", "o"};
Stream<String> arrayStream = Arrays.stream(array);
- Stream的静态方法:of()、iterate()、generate()
// public static<T> Stream<T> of(T... values) {return Arrays.stream(values); }
Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5, 6);
// public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 2).limit(3);
stream2.forEach(System.out::println); //0,2,4
// public static<T> Stream<T> generate(Supplier<? extends T> s) {
// Objects.requireNonNull(s);
// return StreamSupport.stream(
// new StreamSpliterators.InfiniteSupplyingSpliterator.OfRef<>(Long.MAX_VALUE, s), false);
// }
Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
stream3.forEach(System.out::println)
- 双列集合
Map<String,Integer> map = new HashMap<>(){
{
put("aaa",18);put("bbb",20);put("ccc",66);
}
}
Stream<Map.Entry<String,Integer>> stream =map.entrySet().stream()
2.中间操作
- filter()
// 返回由与给定谓词匹配的此流的元素组成的流。
Stream<T> filter(Predicate<? super T> predicate);
- map()
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
- mapToInt()
IntStream mapToInt(ToIntFunction<? super T> mapper);
- flatMap()
// 返回一个流,其中包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果.
// flatMap()操作具有对流的元素应用一对多转换的效果,然后将生成的元素展平为新的流。
// <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
Stream<List<Integer>> inputStream = Stream.of(
Arrays.asList(1),
Arrays.asList(2, 3),
Arrays.asList(4, 5, 6)
);
Stream<Integer> outputStream = inputStream.flatMap((childList) -> childList.stream());
- distinct()
// 返回由该流的不同元素(根据Object.equals(Object) )组成的流。
- sorted()
// Stream<T> sorted();
// Stream<T> sorted(Comparator<? super T> comparator);
List<Person> persons = new ArrayList();
for (int i = 1; i <= 5; i++) {
Person person = new Person(i, "name" + i);
persons.add(person);
}
List<Person> personList2 = persons.stream()
.limit(2)
.sorted((p1, p2) -> p1.getName().compareTo(p2.getName()))
.collect(Collectors.toList());
System.out.println(personList2);
- limit()
// 返回由该流的元素组成的流,截断长度不超过maxSize 。
Stream<T> limit(long maxSize);
- peek()
// 返回由该流的元素组成的流,并在从结果流中消耗元素时对每个元素执行提供的操作
// 此方法的存在主要是为了支持调试,您希望在元素流过管道中的某个点时查看它们:
Stream<T> peek(Consumer<? super T> action);
- skip()
// 在丢弃流的前n元素后,返回由该流的剩余元素组成的流。如果此流包含少于n元素,则将返回一个空流。
Stream<T> skip(long n);
3.终结操作
- count()
long count();
- min()&max()
Optional<T> max(Comparator<? super T> comparator);
- anyMatch()
// 返回此流的任何元素是否与提供的谓词匹配。如果不需要确定结果,则可能不会评估所有元素的谓词。是一个短路终端操作。
boolean anyMatch(Predicate<? super T> predicate);
- allMatch()
// 返回此流的所有元素是否与提供的谓词匹配。如果不需要确定结果,
boolean allMatch(Predicate<? super T> predicate);
- noneMatch()
- findFirst()
// 返回一个描述此流的第一个元素的Optional
Optional<T> findFirst();
- findAny()
Optional<T> findAny();
- toArray()
// Object [] toArray();
// <A> A[] toArray(IntFunction<A[]> generator);
List<String> strList = Arrays.asList( "Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");
Object [] strAryNoArg = strList.stream().toArray();
String [] strAry = strList.stream().toArray(String[]::new);
- collect()
//收集器,它接收的参数是将流中的元素累积到汇总结果的各种方式
<R, A> R collect(Collector<? super T, A, R> collector);
//常见参数
List<Menu> menus=Menu.getMenus.stream().collect(Collectors.toList());
Set<Menu> menus=Menu.getMenus.stream().collect(Collectors.toSet());
//把流中所有元素收集到给定的供应源创建的集合中
ArrayList<Menu> menus=Menu.getMenus.stream().collect(Collectors.toCollection(ArrayList::new));
Map<String,List<Book>> map =authors.stream().distinct().collect(Collectors.toMap(a->a.getName,a->a.getBooks()));
- reduce()
该接口含有3种调用方式:
Optional<T> reduce(BinaryOperator<T> accumulator);
T reduce(T identity, BinaryOperator<T> accumulator);
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner);
//1个参数的接口内部效果
boolean foundAny = false;
T result = null;
for (T element : this stream) {
if (!foundAny) {
foundAny = true;
result = element;
}
else
result = accumulator.apply(result, element);
}
return foundAny ? Optional.of(result) : Optional.empty();
//2个参数的接口
T result = identity;
for (T element : this stream){
result = accumulator.apply(result, element)
}
return result;
//egg
List<Integer> num = Arrays.asList(1, 2, 4, 5, 6, 7);
Integer integer = num.stream().reduce(new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer a, Integer b) {
System.out.println("x:"+a);
return a + b;
}
//integer=25
//Integer integer3 = num.stream().reduce((integer1, integer2) -> integer1 + integer2).get();
4.转化为其它数据结构
// 1. Array
String[] strArray1 = stream.toArray(String[]::new);
// 2. Collection
List<String> list1 = stream.collect(Collectors.toList());
List<String> list2 = stream.collect(Collectors.toCollection(ArrayList::new));
Set set1 = stream.collect(Collectors.toSet());
Stack stack1 = stream.collect(Collectors.toCollection(Stack::new));
// 3. String
String str = stream.collect(Collectors.joining()).toString();
部分内容来源于网上,侵删。