java lambda expression and stream
1. Lambda Expressions
java 8 introduced Lambda expression, to simplify implementation of the interface method abstract single
Parameter type does not require declaration, the type of the parameter automatically infer
Abstract interface is called a single method of interface function, denoted as@FunctionalInterface
- The method java single interface:
- Comparator
- Runnable
- Callable
example:
import java.util.Arrays;
import java.util.Comparator;
public class LambdaSample {
public static void main(String[] args) throws Exception {
String[] words = "Improving code with Lambda expressions in Java".split(" ");
// Arrays.sort(words, new Comparator<String>() {
// @Override
// public int compare(String s1, String s2) {
// // 忽略大小写排序:
// return s1.toLowerCase().compareTo(s2.toLowerCase());
// }
// });
Arrays.sort(words, (s1, s2) -> {
return s1.toLowerCase().compareTo(s2.toLowerCase());
});
System.out.println(Arrays.toString(words));
}
}
s1, s2: incoming parameters
-> {}: Process Method
Runnable () Exercise:
public class LambdaPractice {
public static void main(String[] args) throws Exception {
// TODO: 将Runnable改为lambda表达式:
// Thread t = new Thread(new Runnable() {
// @Override
// public void run() {
// System.out.println("start new thread...");
// }
// });
// t.start();
// t.join();
Thread t = new Thread(() -> {
System.out.println("start new thread");
});
t.start();
t.join();
}
}
2. The method of introducing (java8 of: :)
jdk8 used in :: usage. The format is as a method parameter passed to internal stream, so that each element of the stream which are passed to the method is performed at double colon operator is in Java [reference method], [reference method] is:
类名::方法名
Note here not ().
Code Example:
import java.util.Arrays;
class SortedBy {
static int name(String s1, String s2) {
return s1.compareTo(s2);
}
static int nameIgnoreCase(String s1, String s2) {
return s1.toLowerCase().compareTo(s2.toLowerCase());
}
static int length(String s1, String s2) {
int n1 = s1.length();
int n2 = s2.length();
if (n1 == n2) {
return s1.compareTo(s2);
}
return n1 < n2 ? -1 : 1;
}
}
public class LambdaSort {
public static void main(String[] args) throws Exception {
String[] array = "Java Apple lambda functional OOP".split(" ");
Arrays.sort(array, SortedBy::name);
System.out.println(Arrays.toString(array));
}
}
- Anonymous class
Anonymous classes, that is not the name of the class, which is the name given by the Java compiler, typically the form: $ + + class name external anonymous type sequence, i.e. no name can not be referenced elsewhere, can not be instantiated, only once Of course you can not have a constructor.
Anonymous class constructor is using the parent class and class member itself is configured as a class.
Format: new parent class () {} subclass content
Out out = new Out() {
void show() {
System.out.printIn("run in Inner");
}
}
3. Stream
Introduction 3.1 Stream
In Java8 introduces a new Stream API, in java.uti.stream package
Stream API features:
- Stream API provides a set of abstract new sequence streamed
- Stream API supports into functional / chaining
- Stream is an infinite sequence can be, and in most cases inert calculated
Unlike in java.io stream API InputStream and OutputStream:
java.io | Java.util.stream | |
---|---|---|
storage | Sequential read byte / char | Sequentially output in any java object |
use | Serialized to a file / network | Memory computing / business logic |
Unlike stream API java.util.List:
Jav.util.List | java.util.stream | |
---|---|---|
element | It has been allocated and stored in memory | For the distribution, real-time computing |
use | Operating a set of objects existing java | Lazy evaluation |
- Lazy evaluation
Stream<BigInteger> naturals = createNaturalStrem(); //不计算
Stream<BigInteger> s2 = naturals.map((n) -> n.multiply(n)); // 不计算
Stream<BigInteger> s3 = s2.limit(100); // 不计算
s3.forEach(System.out::printLn); // 计算
3.2 Stream created
- Created by specifying the element / existing array / Existing Collection
- strem.of(T… t)
- Array.strem(array)
- collection.stream()
- Created by Supplier
- Created by other types of related methods
- Stream has basic types: IntStrem / LongStream / DoubleStream
example:
package javatest;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* @ClassName TestB
* @Description TODO
* @Author lingxiangxiang
* @Date 11:37 AM
* @Version 1.0
**/
public class TestB {
public static void main(String[] args) {
String[] a = new String[]{"a", "b", "c", "d"};
int[] b = new int[]{1, 2, 3, 4, 5};
List<Integer> l1 = Arrays.asList(1, 2, 3, 4, 5);
// 1. 通过Stream.of来创建
Stream<Integer> s1 = Stream.of(1, 2, 3, 4, 5);
// 2. 通过数组来创建
Stream<String> s2 = Arrays.stream(a);
// Stream<Integer> s3 = Arrays.stream(b); // 这样的方法时错误的
IntStream s4 = Arrays.stream(b);
// 3. 通过Collection来创建
Stream<Integer> s5 = l1.stream();
// 4. 通过Supplier来创建
Stream<BigInteger> s6 = Stream.generate(new NaturalSupplier());
s1.forEach(System.out::println);
s2.forEach(System.out::println);
s4.forEach(System.out::println);
s5.forEach(System.out::println);
// limit的限定个数
s6.limit(10).forEach(System.out::println);
}
}
class NaturalSupplier implements Supplier<BigInteger> {
BigInteger next = BigInteger.ZERO;
@Override
public BigInteger get() {
next = next.add(BigInteger.ONE);
return next;
}
}
3.3 Stream common method
3.3.1 map
map()
Method: Stream mapping each element into a further element and generate a new Stream, an element can be converted into another type of element
// 例子1
import java.util.Arrays;
import java.util.stream.Stream;
public class StreamMapSample {
public static void main(String[] args) throws Exception {
String[] array = "Stream API supports functional-style operations".split(" ");
Stream<String> stream = Arrays.stream(array);
stream.map(String::toUpperCase).forEach(System.out::println);
}
}
// 例子2
import java.util.Arrays;
import java.util.stream.Stream;
class Person {
String name;
char gender;
public Person(String name, char gender) {
this.name = name;
this.gender = gender;
}
public String toString() {
return "Persion(" + name + ", " + gender + ")";
}
}
public class StreamMapSample2 {
public static void main(String[] args) throws Exception {
String[] inputs = { "Bob,M", "Alice,F", "Time,M", "Lily,F" };
Stream<String> names = Arrays.stream(inputs);
Stream<Person> persons = names.map((s) -> {
int n = s.indexOf(',');
String name = s.substring(0, n);
char gender = s.charAt(n + 1);
return new Person(name, gender);
});
persons.forEach(System.out::println);
}
}
3.3.2 filter
Each element of a Stream tested by the test element to generate a new Stream after filtration, exclusion conditions are not satisfied for element
// 例子1
import java.util.function.Supplier;
import java.util.stream.Stream;
class NaturalSupplier implements Supplier<Long> {
long x = 0;
public Long get() {
x++;
return x;
}
}
public class StreamFilterSample {
public static void main(String[] args) throws Exception {
Stream<Long> natural = Stream.generate(new NaturalSupplier());
Stream<Long> odd = natural.filter((n) -> n % 2 == 1);
odd.limit(20).forEach(System.out::println);
}
}
// 例子2
import java.util.Arrays;
import java.util.stream.Stream;
public class StreamFilterSample2 {
public static void main(String[] args) throws Exception {
String[] array = { "Java", " Python ", " ", null, "\n\n", " Ruby " };
Stream<String> normalized = Arrays.stream(array).filter(s -> s != null && !s.trim().isEmpty())
.map(s -> s.trim());
normalized.forEach(System.out::println);
}
}
3.3.3 reduce
reduce()
method:
- Each element in turn acts on a Stream BiFunction, and the combined result
- reduce polymerization method
- The polymerization process of the immediately calculates Stream
public class StreamReduceSample {
public static void main(String[] args) throws Exception {
int r = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).reduce((acc, x) -> acc * x).get();
System.out.println(r);
System.out.println(1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9);
}
}
3.3.4 forEach
Comparison of pre-java8 and forEach
// 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());
}
}
3.3.5 Other operations
java.util.stream.Stream provides many useful features:
Conversion operations: map, filter, sorted, distinct (de-emphasis)
Merge operation: concat, flatMap
Parallel processing: parallel
Polymerization operation: reduce, count, max, min, sum, average
Other operations: allMatch, anyMatch, forEach
Stream converted to set / array type: toArray, collect
limit (10): Take 10
And forwards law three: (3) skip
s5.sorted(Comparator.reverseOrder()).forEach(System.out::println);