Learning new features of Java 8

Posted by corruption on Thu, 10 Feb 2022 21:25:53 +0100

1, Lambda expression

1. Basic syntax of lambda expression

       java 8 introduces a new operator "- >", the arrow operator / lambda operator, and the arrow operator divides the lambda expression into two parts:
Left: of lambda parameter On the right side of the list: the functions to be performed in lambda, that is, lambda body

• syntax format 1: None parameter , no return value: () - > specific function

• syntax format 2: there is one parameter Specific function: (x) - > return value

• syntax format 3: if there is only one parameter,parameter Parentheses can be omitted without writing: X - > specific functions

• syntax format 4: there are more than two parameter , there are multiple statements in the lambda body with return values:

• syntax format 5: there are two parameters. There is only one statement in the lambda body. There is a return value, {} and return can be omitted

• syntax format 6: the data type of lambda expression can be omitted without writing, because the jvm compiler can infer the data type through the context, that is, type inference

Pithy formula: • left and right encounter a parenthesis

• left inferred type Province

A limitation of lambda expressions is that they can only reference final or final local variables, which means that variables defined outside the domain cannot be modified inside lambda.

List<Integer> primes = Arrays.asList(new Integer[]{2, 3,5,7});
int factor = 2;
primes.forEach(element -> { factor++; });

Compile time error: "local variables referenced from a lambda expression must be final or effectively final" in addition, it is possible to access it without modification, as shown below:

List<Integer> primes = Arrays.asList(new Integer[]{2, 3,5,7});
int factor = 2;
primes.forEach(element -> { System.out.println(factor*element); });

 2. Inert evaluation method

lists.stream().filter(f -> f.getName().equals("p1"))

In the above example, this line of code does not do any practical work. The filter only describes the Stream and does not generate a new set.

Early evaluation method

List<Person> list2 = lists.stream().filter(f -> f.getName().equals("p1")).collect(Collectors.toList());

As shown in the example above, collect will eventually generate a new value from the Stream and have the termination operation.

3.stream & parallelStream

Each Stream has two modes: sequential execution and parallel execution. Parallel streams are twice as fast as sequential streams.

Sequential stream:

List <Person> people = list.getStream.collect(Collectors.toList());

Parallel stream

List <Person> people = list.getStream.parallel().collect(Collectors.toList());

As the name suggests, when traversing in a sequential manner, read each item before reading the next item. When traversing in parallel, the array will be divided into multiple segments, each of which will be processed in different threads, and then the results will be output together.

Ownership of copyright https://pdai.tech All. Link: Java 8 - functional programming (lambda expression) | Java full stack knowledge system

Common methods in Stream are as follows:

  • stream(), parallelStream()
  • filter()
  • findAny() findFirst()
  • sort
  • forEach void
  • map(), reduce()
  • flatMap() - connect multiple streams into one Stream
  • collect(Collectors.toList())
    • Collectors.joining(", ")
    • Collectors.toList()
    • Collectors.toSet() to generate a set set
    • Collectors.toMap(MemberModel::getUid, Function.identity())
    • Collectors.toMap(ImageModel::getAid, o -> IMAGE_ADDRESS_PREFIX + o.getUrl())
  • distinct, limit
  • count
  • min, max, summaryStatistics





public @interface FunctionalInterface{}

5. Practical examples

(1) Processing string

Two new methods can be used on string classes: join and chars. The first method concatenates any number of strings into one string using the specified delimiter.

String.join(":", "foobar", "foo", "bar");
// => foobar:foo:bar

The second method, chars, creates a data stream from all characters of the string, so you can use streaming operations on these characters.

    .mapToObj(c -> String.valueOf((char)c))
// => :abfor

(2) Set -- "take an attribute of an element --" de duplication -- "assemble into List --" return

List<LikeDO> likeDOs=new ArrayList<LikeDO>();
List<Long> likeTidList = likeDOs.stream().map(LikeDO::getTid)

(3) Set -- "filter by expression --" traversal and processing of each meta system -- "put into a predefined set

  Map<String, StkProduct> newStockName2Product = Maps.newConcurrentMap();
        stockProducts.stream().filter(stkProduct -> stkProduct.enabled).forEach(stkProduct -> {
            String newName = BCConvert.bj2qj(StringUtils.replace(stkProduct.name, " ", ""));
            newStockName2Product.put(newName, stkProduct);
 Set<String> qjStockNames;
 qjStockNames.stream().filter(name -> !acAutomaton.getKey2link().containsKey(name)).forEach(name -> {
            String value = "";
            StkProduct stkProduct = stockNameQj2Product.get(name);
            if (stkProduct != null) {
                value = stkProduct.name;
            acAutomaton.getKey2link().put(name, value);

(4) Set -- map

List<ImageModel> imageModelList = null;
Map<Long, String> imagesMap = null;
imagesMap = imageModelList.stream().collect(Collectors.toMap(ImageModel::getAid, o -> IMAGE_ADDRESS_PREFIX + o.getUrl()));

Map<String, String> kvMap = postDetailCacheList.stream().collect(Collectors.toMap((detailCache) ->
                getBbsSimplePostKey(detailCache.getTid()), JSON::toJSONString));

Map<Long, Long> pidToTid;
List<String> pidKeyList = pidToTid.entrySet().stream().map((o) -> getKeyBbsReplyPid(o.getValue(), o.getKey())).collect(Collectors.toList());

(5) phones is a list < string >, which groups and classifies the same elements

List<String> phones=new ArrayList<String>();
        Map<String, List<String>> phoneClassify = phones.stream().collect(Collectors.groupingBy(item -> item));
Return results: 
{a=[a, a, a], b=[b, b], c=[c]}

Topics: html linq p2p