Java8 学习笔记

94 阅读4分钟

Java8 学习笔记

Introduction

  1. Lambda;
  2. Functional Interface;
  3. Default Methods;
  4. Java 8 Streams;
  5. Java 8 Date/Time API;

Java 8 forEach

  1. Java 8 stream forEach example
  • 迭代输出流内的元素:
ArrayList<Integer> numberList = new ArrayList<>(Arrays.asList(1,2,3,4,5));
     
Consumer<Integer> action = System.out::println;
 
numberList.stream().filter(n -> n%2  == 0).forEach( action );

  • 遍历arraylist所有元素:
ArrayList<Integer> numberList = new ArrayList<>(Arrays.asList(1,2,3,4,5));
     
Consumer<Integer> action = System.out::println;
 
numberList.forEach(action);


  • 遍历HashMap所有条目:

HashMap<String, Integer> map = new HashMap<>();
        map.put("A", 1);
        map.put("B", 2);
        map.put("C", 3);

        //1. Map entries
        Consumer<Map.Entry<String, Integer>> action = System.out::println;
        System.out.println("Map entries--------------------");
        map.entrySet().forEach(action);
	
	/*
	Map entries--------------------
	A=1
	B=2
	C=3	
	*/

        //2. Map keys
        Consumer<String> actionOnKeys = System.out::println;
        System.out.println("Map keys +++++++++++++++++++++++");
        map.keySet().forEach(actionOnKeys);

	/*
	Map keys +++++++++++++++++++++++
	A
	B
	C
	*/

        //3. Map values
        Consumer<Integer> actionOnValues = System.out::println;
        System.out.println("Map values ======================");
        map.values().forEach(actionOnValues);
	
	/*
	Map values ======================
	1
	2
	3
	*/

  • 集合自定义执行逻辑:
HashMap<String, Integer> map = new HashMap<>();
     
	map.put("A", 1);
	map.put("B", 2);
	map.put("C", 3);
 
Consumer<Map.Entry<String, Integer>> action = entry -> 
{ 
    	System.out.println("Key is : " + entry.getKey()); 
   	System.out.println("Value is : " + entry.getValue()); 
}; 
 
	map.entrySet().forEach(action);

	/*
	Key is : A
	Value is : 1
 
	Key is : B
	Value is : 2
 
	Key is : C
	Value is : 3
	*/



Java 8 Stream API

  • Different ways to create streams
  1. Stream.of(val1,val2,val3...)
public class StreamBuilders 
{
     public static void main(String[] args)
     {
         Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9);
         stream.forEach(p -> System.out.println(p));
     }
}

  1. Stream.of(arrayOfElements)
	 Stream<Integer> stream = Stream.of( new Integer[]{1,2,3,4,5,6,7,8,9} );
         stream.forEach(p -> System.out.println(p));

  1. List.stream()
List<Integer> list = new ArrayList<Integer>();
 
         for(int i = 1; i< 10; i++){
             list.add(i);
         }
 
         Stream<Integer> stream = list.stream();
         stream.forEach(p -> System.out.println(p));

  1. Stream.generate() or Stream.iterate()
	 Stream<Date> stream = Stream.generate(() -> { return new Date(); });
         stream.forEach(p -> System.out.println(p));

  1. String chars or String tokens
	IntStream stream = "12345_abcdefg".chars();
        stream.forEach(p -> System.out.println(p));
         
        //OR
         
        Stream<String> stream = Stream.of("A$B$C".split("\\$"));
        stream.forEach(p -> System.out.println(p));

  • Convert streams to collections
  1. Convert Stream to List-Stream.collect(Collectors.toList())
 List<Integer> list = new ArrayList<Integer>();
         for(int i = 1; i< 10; i++){
             list.add(i);
         }
         Stream<Integer> stream = list.stream();
         List<Integer> evenNumbersList = stream.filter(i -> i%2 == 0).collect(Collectors.toList());
         System.out.print(evenNumbersList);  
  1. ConvertStream to array-Strem.toArray(EntryType[]::new)
List<Integer> list = new ArrayList<Integer>();
         for(int i = 1; i< 10; i++){
             list.add(i);
         }
         Stream<Integer> stream = list.stream();
         Integer[] evenNumbersArr = stream.filter(i -> i%2 == 0).toArray(Integer[]::new);
         System.out.print(evenNumbersArr);  
  • Core stream opoerations
List<String> memberNames = new ArrayList<>();
memberNames.add("Amitabh");
memberNames.add("Shekhar");
memberNames.add("Aman");
memberNames.add("Rahul");
memberNames.add("Shahrukh");
memberNames.add("Salman");
memberNames.add("Yana");
memberNames.add("Lokesh");  

  1. 中间操作返回流本身
    1.1 stream.filter()

Filter过滤流中的所有元素,中间操作

memberNames.stream().filter((s)->s.startWith("A")).forEach(System.out::println);  

1.2 stream.map()

映射通过给定的函数将每个元素转换成另外一个对象

memberNames.stream().filter((s) -> s.startsWith("A"))
                     .map(String::toUpperCase)
                     .forEach(System.out::println);  

1.3 stream.sorted()
元素将以自然顺序排序

memberNames.stream().sorted()
                    .map(String::toUpperCase)
                    .forEach(System.out::println);  
  1. Terminal operations
    终端操作返回某种类型的结果,而不是流。

2.1 stream.forEach()
迭代流中每个元素,并对此执行一些操作。该操作作为Lambda表达式参数传递。

memberNames.forEach(System.out::println);  

2.2 stream.collect()
collect()方法用于从流中接收元素并存储在集合中。

List<String> memberNamesInUppercase = memberNames.stream().sorted().map(String::toUpperCase).collect(Collectors.toList());  
System.out.print(memberNamesInUppercase);  

2.3 stream.match() 各种匹配操作可用于检查某个谓词是否与流匹配。 所有这些操作都是终端操作,并返回布尔结果。

boolean matchedResult = memberNames.stream()
                    .anyMatch((s) -> s.startsWith("A"));
 
System.out.println(matchedResult);
 
matchedResult = memberNames.stream()
                    .allMatch((s) -> s.startsWith("A"));
 
System.out.println(matchedResult);
 
matchedResult = memberNames.stream()
                    .noneMatch((s) -> s.startsWith("A"));
 
System.out.println(matchedResult);
 
Output: 
 
true
false
false  

2.4 stream.count()
Count是一个终端操作,将流中的元素数返回为long。

long totalMatched = memberNames.stream()
                    .filter((s) -> s.startsWith("A"))
                    .count();
 
System.out.println(totalMatched);

2.5 stream.reduce()

Optional<String> reduced = memberNames.stream()
                    .reduce((s1,s2) -> s1 + "#" + s2);
 
reduced.ifPresent(System.out::println);
 
Output: Amitabh#Shekhar#Aman#Rahul#Shahrukh#Salman#Yana#Lokesh
  1. Stream short-circuit operations
    3.1 stream.anyMatch()
    流中任一元素满足条件,方法返回true,不再处理任何元素。
boolean matched = memberNames.stream()
                    .anyMatch((s) -> s.startsWith("A"));
 
System.out.println(matched);
 
Output: true  

3.2 stream.findFirst()
返回流中第一个元素后,不再处理任何元素。

String firstMatchedName = memberNames.stream()
                .filter((s) -> s.startsWith("L"))
                .findFirst().get();
 
System.out.println(firstMatchedName);
 
Output: Lokesh  
  1. Parallelism in Java Steam
    在并行内核中使用多个线程来完成特定工作时,都必须调用方法parallelStream()方法而不是stream()方法。
List<Integer> list = new ArrayList<Integer>();
         for(int i = 1; i< 10; i++){
             list.add(i);
         }
         //Here creating a parallel stream
         Stream<Integer> stream = list.parallelStream();  
         Integer[] evenNumbersArr = stream.filter(i -> i%2 == 0).toArray(Integer[]::new);
         System.out.print(evenNumbersArr);  

Boxed Stream

流转换成其他类型时首先将元素包装在包装器类中,这种类型的流称为boxed stream:IntStream 、LongStream、DoubleStream

  1. 将int流转换为Integers列表的示例
List<Integer> ints = IntStream.of(1,2,3,4,5)
                .boxed()
                .collect(Collectors.toList());
        System.out.println(ints);
        Optional<Integer> max = IntStream.of(1,2,3,4,5)
                .boxed()
                .max(Integer::compareTo);
        System.out.println(max);  
/*
[1, 2, 3, 4, 5]
Optional[5]
*/

Lambda Expression

Lambda表达式(或函数)只是一个匿名函数,即不带名称且不受标识符限制的函数。

  1. Lambda Syntax
(x, y) -> x + y    
//or
() -> expression  
//or  
(param) -> expression  
//or  
(param) -> { statements;}  

  1. Lambda表达式的一些功能:
  • Lambda表达式可以具有零个,一个或多个参数。
  • 参数的类型可以显式声明,也可以从上下文中推断出来。
  • 多个参数用强制括号括起来,并用逗号分隔。 空括号用于表示空参数集。
  • 当有单个参数时,如果推断出其类型,则不强制使用括号。 例如a->返回a * a。
  • Lambda表达式的主体可以包含零个,一个或多个语句。
  • 如果lambda表达式的主体具有单个语句,则不必使用大括号,并且匿名函数的返回类型与主体表达式的返回类型相同。 如果正文中的陈述多于一个,则这些陈述必须用大括号括起来。
  1. Java 8 functional interface
    转换lambda表达式的类型始终是函数接口类型

单一抽象方法接口 (SAM接口),这意味着只能使用一种方法进行接口,又被称为功能接口 。 Java 8通过使用新的注解@FunctionalInterface标记这些接口来实施单一职责规则。

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

@FunctionalInterface注解的接口,只允许使用一种抽象方法,否则会报错。

@FunctionalInterface
interface functionalInterface {
    public void firstWork();
    public void doSomeMoreWork();   //error 注解飘红
}  

有效的功能接口:

@FunctionalInterface
interface functionalInterface {
    public void firstWork();
    //从概念上讲,功能接口仅具有一种抽象方法。 由于default methods具有实现,因此它们不是抽象的
    default void doSomeMoreWork1(){
        //Method body
    }
    
    @Override
    public String toString();                //Overridden from Object class
    //
    @Override
    public boolean equals(Object obj);
}  

记录学习笔记,主要学习网站rumenz.com,如有问题请联系谢谢。