JDK8新特性笔记(持续更新中)

JDK1.8新特性

jdk1.8新特性知识点:

        Lambda表达式
        函数式接口
        *方法引用和构造器调用
        Stream API
        接口中的默认方法和静态方法
        新时间日期API

Lambda表达式

lambda表达式本质上是一段匿名内部类,也可以是一段可以传递的代码

lambda最直观的优点:简洁代码

            目标方法的参数是一个接口
            接口中只有一个抽象方法,这个抽象方法不是Object里面的方法
            接口最好顶一个注解:@FunctionalInterface
            lambda如何写开发:
            把接口中抽象的方法复制一份到代码中(一定要加注释)
               接口中唯一的抽象方法`在这里插入代码
               	 * public abstract void run();
		 * 最全的写法:它是唯一的抽象方法的简写
		 * 	(方法的形参) -> {方法体,如果有返回值,一定要写返回值}
		 * 最全的省略:
		 * 		如果目标方法只有一个参数,可以省略小括号
		 * 		小括号里面的形参:类型可以省略
		 * 		如果方法体只有一行,大括号可以省略
常见的lambda表达式接口
所有的lambda表达式常见的工具类都在java.util.function
//匿名内部类
  Comparator<Integer> cpt = new Comparator<Integer>() {
      @Override
      public int compare(Integer o1, Integer o2) {
          return Integer.compare(o1,o2);
      }
  };

  TreeSet<Integer> set = new TreeSet<>(cpt);

  System.out.println("=========================");

  //使用lambda表达式
  Comparator<Integer> cpt2 = (x,y) -> Integer.compare(x,y);
  TreeSet<Integer> set2 = new TreeSet<>(cpt2);

Lmabda表达式的语法总结: () -> ();

前置语法
无参数无返回值() -> System.out.println(“Hello WOrld”)
有一个参数无返回值(x) -> System.out.println(x)
有且只有一个参数无返回值x -> System.out.println(x)
有多个参数,有返回值,有多条lambda体语句(x,y) -> {System.out.println(“xxx”);return xxxx;}
有多个参数,有返回值,只有一条lambda体语句(x,y) -> xxxx

口诀:左右遇一省括号,左侧推断类型省
注:当一个接口中存在多个抽象方法时,如果使用lambda表达式,并不能智能匹配对应的抽象方法,因此引入了函数式接口的概念

函数式接口

接口默认方法

interface MyInterface {
	// 这个方法不重要
    void print();
	// 接口默认方法
    default void defaultMethod(){
        System.out.println("接口默认实现方法...");
    }

}

/**
 * 接口默认方法测试
 *
 * @author 七夜雪
 * @date 2019-01-09 7:12
 */
public class InterfaceDefaultMethod {

    public static void main(String[] args) {
	    // lambda表达式实现接口
        MyInterface myInterface = () -> {};
        myInterface.defaultMethod();
    }
}

在这里插入图片描述

函数式接口的提出是为了给Lambda表达式的使用提供更好的支持。

函数式接口的提出是为了给Lambda表达式的使用提供更好的支持。
什么是函数式接口?
简单来说就是只定义了一个抽象方法的接口(Object类的public方法除外),就是函数式接口,并且还提供了注解:@FunctionalInterface

Stream接口的方法可以归为两类(算子就是方法)
方法的返回值还是Stream:(Transformaction算子)
方法的返回值不是Stream:(action算子)
数据流:
一根管子,一个数据会把所有的管子走完以后,再走第二个数据;
而不是所有的数据走完第一个管子以后,再一块走第二个管子
在这里插入图片描述
在这里插入图片描述

常见的四大函数式接口

在这里插入图片描述

  • Consumer 《T》:消费型接口,有参无返回值
    @Test
    public void test(){
        changeStr("hello",(str) -> System.out.println(str));
    }

    /**
     *  Consumer<T> 消费型接口
     * @param str
     * @param con
     */
    public void changeStr(String str, Consumer<String> con){
        con.accept(str);
    }
  • Supplier 《T》:供给型接口,无参有返回值
    @Test
    public void test2(){
        String value = getValue(() -> "hello");
        System.out.println(value);
    }

    /**
     *  Supplier<T> 供给型接口
     * @param sup
     * @return
     */
    public String getValue(Supplier<String> sup){
        return sup.get();
    }
  • Function 《T,R》::函数式接口,有参有返回值
    @Test
    public void test3(){
        Long result = changeNum(100L, (x) -> x + 200L);
        System.out.println(result);
    }

    /**
     *  Function<T,R> 函数式接口
     * @param num
     * @param fun
     * @return
     */
    public Long changeNum(Long num, Function<Long, Long> fun){
        return fun.apply(num);
    }
  • Predicate《T》: 断言型接口,有参有返回值,返回值是boolean类型
public void test4(){
        boolean result = changeBoolean("hello", (str) -> str.length() > 5);
        System.out.println(result);
    }

    /**
     *  Predicate<T> 断言型接口
     * @param str
     * @param pre
     * @return
     */
    public boolean changeBoolean(String str, Predicate<String> pre){
        return pre.test(str);
    }

函数式接口的提出是为了让我们更加方便的使用lambda表达式,不需要自己再手动创建一个函数式接口,直接拿来用就好了

方法引用

若lambda体中的内容有方法已经实现了,那么可以使用“方法引用”
也可以理解为方法引用是lambda表达式的另外一种表现形式并且其语法比lambda表达式更加简单
  • 方法引用的三种表现形式:
    1. 对象::实例方法名
    2. 类::静态方法名
    3. 类::实例方法名 (lambda参数列表中第一个参数是实例方法的调用 者,第二个参数是实例方法的参数时可用)
 public void test() {
        /**
        *注意:
        *   1.lambda体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保持一致!
        *   2.若lambda参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName::method
        *
        */
        Consumer<Integer> con = (x) -> System.out.println(x);
        con.accept(100);

        // 方法引用-对象::实例方法
        Consumer<Integer> con2 = System.out::println;
        con2.accept(200);

        // 方法引用-类名::静态方法名
        BiFunction<Integer, Integer, Integer> biFun = (x, y) -> Integer.compare(x, y);
        BiFunction<Integer, Integer, Integer> biFun2 = Integer::compare;
        Integer result = biFun2.apply(100, 200);

        // 方法引用-类名::实例方法名
        BiFunction<String, String, Boolean> fun1 = (str1, str2) -> str1.equals(str2);
        BiFunction<String, String, Boolean> fun2 = String::equals;
        Boolean result2 = fun2.apply("hello", "world");
        System.out.println(result2);
    }

构造器引用
格式:ClassName::new


public void test2() {
        // 构造方法引用  类名::new
        Supplier<Employee> sup = () -> new Employee();
        System.out.println(sup.get());
        Supplier<Employee> sup2 = Employee::new;
        System.out.println(sup2.get());
        // 构造方法引用 类名::new (带一个参数)
        Function<Integer, Employee> fun = (x) -> new Employee(x);
        Function<Integer, Employee> fun2 = Employee::new;
        System.out.println(fun2.apply(100));
 }

数组引用
格式:Type[]::new

public void test(){
        // 数组引用
        Function<Integer, String[]> fun = (x) -> new String[x];
        Function<Integer, String[]> fun2 = String[]::new;
        String[] strArray = fun2.apply(10);
        Arrays.stream(strArray).forEach(System.out::println);
}

Stream

获取stream
    // 1、数组   使用的Arrays类的stream方法
    String[] arr = new String[]{"ab", "cd", "ef"};
    Stream<String> arrStream = Arrays.stream(arr);

    stream.forEach(s->System.out.println(s));  //使用完之后不能再使用,需要重新生成  才能再次使用
    // 2、集合   直接使用集合获取流
    List<String> list = Arrays.asList("ab", "cd", "ef");
    Stream<String> colStream = list.stream();
    // 3、值   直接使用静态方法,获取指定值的顺序排序流
    Stream<String> stream = Stream.of("ab", "cd", "ef");
    

常用方法
forEach() 使用该方法迭代流中的每个数据
forEach是一个最终操作,所以我们不能在forEach之后来执行其他Stream操作。

sorted() 使用该方法排序数据

List<OptionHoldDTO>optionHoldDTOList = optionHoldDTOList.stream().filter(optionHoldDTO -> optionHoldDTO.getHoldType() != null)
    .sorted(Comparator.comparingInt(OptionHoldDTO::getHoldType)).collect(Collectors.toList());
list.stream().sorted(Comparator.comparing(User::getAge)).forEach(user -> System.out.println(user));

多个元素排序:coreRspList = coreRspList.stream().sorted( Comparator.comparing(LoanOutStatisticsRspDto::getLoanOutAmount).reversed() .thenComparing(Comparator.comparing(LoanOutStatisticsRspDto::getToLoanOutAmount).reversed()) ).collect(Collectors.toList());

filter():使用该方法过滤

list.stream().filter((User user) -> user.getAge() > 50).forEach(user -> System.out.println(user));

limit():使用该方法截断
// 从第三个开始截断,只输出前三个

list.stream().limit(3).forEach(user -> System.out.println(user));

skip():与limit互斥,使用该方法跳过元素

// 跳过前三个元素,从第四个开始输出
list.stream().skip(3).forEach(user -> System.out.println(user));

Stream操作的三个步骤

  • 创建stream
  • 中间操作(过滤、map)
  • 终止操作
    stream的创建:
    // 1,校验通过Collection 系列集合提供的stream()或者paralleStream()
    List<String> list = new ArrayList<>();
    Strean<String> stream1 = list.stream();

    // 2.通过Arrays的静态方法stream()获取数组流
    String[] str = new String[10];
    Stream<String> stream2 = Arrays.stream(str);

    // 3.通过Stream类中的静态方法of
    Stream<String> stream3 = Stream.of("aa","bb","cc");

    // 4.创建无限流
    // 迭代
    Stream<Integer> stream4 = Stream.iterate(0,(x) -> x+2);

    //生成
    Stream.generate(() ->Math.random());

Stream的中间操作:

/**
   * 筛选 过滤  去重
   */
  emps.stream()
          .filter(e -> e.getAge() > 10)
          .limit(4)
          .skip(4)
          // 需要流中的元素重写hashCode和equals方法
          .distinct()
          .forEach(System.out::println);


  /**
   *  生成新的流 通过map映射
   */
  emps.stream()
          .map((e) -> e.getAge())
          .forEach(System.out::println);


  /**
   *  自然排序  定制排序
   */
  emps.stream()
          .sorted((e1 ,e2) -> {
              if (e1.getAge().equals(e2.getAge())){
                  return e1.getName().compareTo(e2.getName());
              } else{
                  return e1.getAge().compareTo(e2.getAge());
              }
          })
          .forEach(System.out::println);

Stream的终止操作:

 /**
         *      查找和匹配
         *          allMatch-检查是否匹配所有元素
         *          anyMatch-检查是否至少匹配一个元素
         *          noneMatch-检查是否没有匹配所有元素
         *          findFirst-返回第一个元素
         *          findAny-返回当前流中的任意元素
         *          count-返回流中元素的总个数
         *          max-返回流中最大值
         *          min-返回流中最小值
         */

        /**
         *  检查是否匹配元素
         */
        boolean b1 = emps.stream()
                .allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b1);

        boolean b2 = emps.stream()
                .anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b2);

        boolean b3 = emps.stream()
                .noneMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b3);

        Optional<Employee> opt = emps.stream()
                .findFirst();
        System.out.println(opt.get());

        // 并行流
        Optional<Employee> opt2 = emps.parallelStream()
                .findAny();
        System.out.println(opt2.get());

        long count = emps.stream()
                .count();
        System.out.println(count);

        Optional<Employee> max = emps.stream()
                .max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println(max.get());

        Optional<Employee> min = emps.stream()
                .min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        System.out.println(min.get());

末端的操作:

forEach 1 - 对流中的每个元素执行一些操作。
toArray 1 2 - 将流中的元素倾倒入一个数组。
reduce 1 2 3 - 通过一个二进制操作将流中的元素合并到一起。
collect 1 2 - 将流中的元素倾倒入某些容器,例如一个Collection或Map.
min 1 - 根据一个比较器找到流中元素的最小值。
max 1 -根据一个比较器找到流中元素的最大值。
count 1 - 计算流中元素的数量。
anyMatch 1 - 判断流中是否至少有一个元素匹配断言。这是一个短路的操作。
allMatch 1 - 判断流中是否每一个元素都匹配断言。这是一个短路的操作。
noneMatch 1 - 判断流中是否没有一个元素匹配断言。这是一个短路的操作。
findFirst 1 - 查找流中的第一个元素。这是一个短路的操作。
findAny 1 - 查找流中的任意元素,可能对某些流要比findFirst代价低。这是一个短路的操作

并行流和串行流

并行流就是把内容切割成多个数据块,并且使用多个线程分别处理每个数据块的内容。Stream api中声明可以通过parallel()与sequential()方法在并行流和串行流之间进行切换。
接口中可以定义默认实现方法和静态方法
在接口中可以使用default和static关键字来修饰接口中定义的普通方法


public interface Interface {
    default  String getName(){
        return "zhangsan";
    }

    static String getName2(){
        return "zhangsan";
    }
}

4.实战

    * 4.1.特殊的接口
    接口:(com.jinghangzz.jdk_new.inter.IAnimal)
package com.jinghangzz.jdk_new.inter;

import java.util.function.Supplier;

/**
 * 接口:
 * 	为什么接口中的方法要有方法体:
 * 		接口就是为了定标准,这个标准要求所有的实现类,实现抽象方法;
 * 		其实有些方法,所有的实现类代码都是一样的;干脆就把这些代码挪到接口中;
 * 
 * @author TeaBig
 */
public interface IAnimal
{
	/* 属性 */
	int HEAD_NUM = 1 ; 
	/* 下面的写法等同于上面的
	 * 被static修饰的,名字都是大写,
	 * 但是驼峰标识:单词之前使用_隔开
	 *  */
	//public static int HEADNUM = 1 ; 
	
	/* 抽象的方法 */
	/**
	 * 抽象的方法,跑
	 */
	void run();
	/* 丢人的写法 */
	//public abstract void run1();
	
	/* ====新特性开始 ==== */
	/**
	 * 有方法体的方法(普通的方法)
	 * 吃
	 * 要求:
	 * 		必须被default修饰
	 * 		此default和修饰符里面的default不一样
	 * 		它是被public修饰
	 */
	default void eat()
	{
		System.out.println("==IAnimal==eat");
	}
/**
	 * 睡的方法
	 */
	default String sleep()
	{
		System.out.println("==IAnimal==sleep");
		return "===" ; 
	}
	
	/* 静态的方法 */
	static void staticMethod()
	{
		System.out.println("==IAnimal==staticMethod");
	}
	
	/**
	 * 参数是一个接口;
	 * Supplier<IAnimal> supplier(供应商)
	 * @return
	 */
	static IAnimal createObj(Supplier<IAnimal> supplier)
	{
		/* 让供应商去提供供货 */
		return supplier.get() ; 
	}
	/* ====新特性结束 ==== */
}

Person类

package com.jinghangzz.jdk_new.inter;

/**
 * 人,是一个实现类
 * 		如果一个类实现一个接口,就要把接口中所有的抽象方法实现一遍
 * 		也可以实现接口中有方法体的方法(不能是静态方法)
 * @author TeaBig
 */
public class Person implements IAnimal
{
	@Override
	public void run()
	{
		System.out.println("==Person==run");
	}

	@Override
	public void eat()
	{
		/* 调用父类的方法 */
		//IAnimal.super.eat();
		System.out.println("==Person==eat");
	}
}

Dog

package com.jinghangzz.jdk_new.inter;

/**
 * 狗
 * @author TeaBig
 */
public class Dog implements IAnimal
{

	@Override
	public void run()
	{
		System.out.println("==Dog==run");
	}

}

测试类

package com.jinghangzz.jdk_new.inter;

/**
 * 所有的程序的入口函数
 * @author TeaBig
 */
public class ClientMain
{
	public static void main(String[] args)
	{
		System.out.println("==南宋中兴四将==");
		/* 测试第一个
		 * 父类引用指向子类对象
		 *  */
		IAnimal person = new Person();
		/* 调用属性 */
		int headNum = person.HEAD_NUM ; 
		System.out.println("==person.HEAD_NUM==" + headNum);
		/* 接口名.属性 */
		System.out.println("==IAnimal.HEAD_NUM==" + IAnimal.HEAD_NUM);
		/* 调用方法 */
		/* 调用抽象方法 */
		person.run();
		/*=====新知识======*/
		/* 调用的是接口中有方法体的方法 */
		person.eat(); 
		person.sleep();
		/* 调用的是接口中的静态方法 */
		IAnimal.staticMethod();
		
		/*==new对象==*/
//		IAnimal dog = new Dog();
		/* Dog::new	调用的是Dog中的new方法
		 * ::调用方法的简写,左边是类名或者接口名,右边是方法名
		 * 返回值必须是functional Interface;(等讲到lambda表达式的时候再说)
		 * 必须有返回值
		 *  */
		IAnimal dog = IAnimal.createObj(Dog::new);
		System.out.println("==createObj==" + dog);
		IAnimal dog1 = Dog::new;
		/* 调用方法 */
		//String res = dog::sleep;
	}
}

4.2.* lambda
lambda示例代码

package com.jinghangzz.jdk_new.lambda;

import java.util.Date;

/**
 * lambda的测试类
 * 		最终要实现的效果和匿名类很像
 * @author TeaBig
 */
public class LambdaMain
{
	public static void main(String[] args)
	{
		System.out.println("====");
		//lambdaAll();
		

		System.out.println("==main开始==");
		/* 创建线程并启动 
		 * 接口中唯一的抽象方法
		 * public abstract void run();
		 * 最全的写法:它是唯一的抽象方法的简写
		 * 	(方法的形参) -> {方法体,如果有返回值,一定要写返回值}
		 * 最全的省略:
		 * 		如果目标方法只有一个参数,可以省略小括号
		 * 		小括号里面的形参:类型可以省略
		 * 		如果方法体只有一行,大括号可以省略
		 * */
		Thread t = new Thread( () -> System.out.println(Thread.currentThread() + "==计数=="+ "==" + new Date().toLocaleString()) );
		t.start();
		System.out.println("==main结束==");
	
	}

	/**
	 * 最全的写法(lambda)
	 */
	private static void lambdaAll()
	{
		System.out.println("==main开始==");
		/* 创建线程并启动 
		 * 接口中唯一的抽象方法
		 * public abstract void run();
		 * 最全的写法:它是唯一的抽象方法的简写
		 * 	(方法的形参) -> {方法体,如果有返回值,一定要写返回值}
		 * 最全的省略:
		 * 		如果目标方法只有一个参数,可以省略小括号
		 * 		小括号里面的形参:类型可以省略
		 * 		如果方法体只有一行,大括号可以省略
		 * */
		Thread t = new Thread( () -> 
		{
			for (int i = 0; i < 10; i++)
			{
				System.out.println(Thread.currentThread() + "==计数=="+ i +"==" + new Date().toLocaleString());
				try
				{
					Thread.sleep(500);
				} catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
		} );
		t.start();
		System.out.println("==main结束==");
	}
}

Lambda表达式的示例代码

package com.jinghangzz.jdk_new.lambda;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

/**
 * lambda的测试类 最终要实现的效果和匿名类很像
 * 	如果看到一个方法的参数类型后面跟了一个...
 * 		在方法定义的时候,把这三个点的参数,当成数组使用(String ... str)(String[] str)效果一样
 * 		在方法使用的时候,这三个点要传入实参,实参的个数随便填写
 * 		...必须是方法形参的最后一个
 * ~示例:方法调用时(String[] str)
 * String[] str = {"1","2","3"} ;
 * 	目标方法(str) 
 * ~方法调用时String ... str
 * 	目标方法("1","2","3","3","3","3","3","3")
 * @author TeaBig
 */
public class LambdaTest
{
	public static void main(String[] args)
	{
		System.out.println("====");
		/* 调用方法 */
		String[] str = {"1","a","b","c","d"};
		//method1Arr(str,"2");
		/* 调用方法 */
		//method2Point(str);
		method2Point(1,"1","a","b","c","d","e");
		/* 集合抽取lambda */
		lambdaList();
	}

	/**
	 * lambda表达式,测试类
	 */
	private static void lambdaList()
	{
		/* 准备一个List */
		List<String> list = Arrays.asList("1","a","b","c","d");
		/* 如何循环
		 * void accept(T t);
		 * (类型忽略,直接写名字,形参名,名字随便写)
		 *  */
//		list.forEach( (t) -> 
//		{
//			System.out.println("==lambda循环==" + t);
//		} );
		/* 超级简单的写法 */
		list.forEach( t -> System.out.println("==lambda循环==" + t));
		/* 匿名类
		 * 泛型是和容器的泛型一致
		 *  */
		list.forEach(new Consumer<String>()
		{
			@Override
			public void accept(String t)
			{
				System.out.println("==Consumer循环==" + t) ; 
			}
		});
	}
	
	/**
	 * 方法的形参是数组
	 * @param str
	 */
	public static void method1Arr(String[] str)
	{
		/* 查看数组里面的内容 */
		for (int i = 0; i < str.length; i++)
		{
			String temp = str[i];
			System.out.println(i + "==method1Arr==" + temp);
		}
	}
	
	/**
	 * 方法的形参是三个点
	 * @param str
	 */
	public static void method2Point(int j , String... str)
	{
		/* 查看数组里面的内容 */
		for (int i = 0; i < str.length; i++)
		{
			String temp = str[i];
			System.out.println(i + "==method2Point==" + temp);
		}
	}
}

数据流编程

1.transformaction算子

package com.jinghangzz.jdk_new.stream;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;

import org.junit.Test;

/**
 * 数据流编程
 * @author TeaBig
 */
public class DataStream
{
	/**
	 * 测试一个方法(框架)
	 */
	@Test
	public void base()
	{
		/* 准备一个容器 */
		List<Integer> intList = Arrays.asList(100,2,38,12,50,87);
		/* 准备一个Stream */
		Stream<Integer> souStream = null;
		try
		{
			souStream = intList.stream(); 
			/* 并行:多线程 */
			//souStream = intList.parallelStream();
			System.out.println("=isParallel==>" + souStream.isParallel());
			/* 循环数据
			 * java.util.function.Consumer
			 * void accept(T t);
			 * 
			 * forEach:action算子
			 *  */
			souStream.forEach( t -> System.out.println("==Stream循环==" + t));
		} catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally
		{
			if(souStream != null)
			{
				souStream.close();
				souStream = null ; 
			}
		}
		package com.jinghangzz.jdk_new.stream;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;

import org.junit.Test;

/**
 * 数据流编程
 * @author TeaBig
 */
public class DataStream
{
	/**
	 * 测试一个方法(框架)
	 */
	@Test
	public void base()
	{
		/* 准备一个容器 */
		List<Integer> intList = Arrays.asList(100,2,38,12,50,87);
		/* 准备一个Stream */
		Stream<Integer> souStream = null;
		try
		{
			souStream = intList.stream(); 
			/* 并行:多线程 */
			//souStream = intList.parallelStream();
			System.out.println("=isParallel==>" + souStream.isParallel());
			/* 循环数据
			 * java.util.function.Consumer
			 * void accept(T t);
			 * 
			 * forEach:action算子
			 *  */
			souStream.forEach( t -> System.out.println("==Stream循环==" + t));
		} catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally
		{
			if(souStream != null)
			{
				souStream.close();
				souStream = null ; 
			}
		}
	}
	
	/**
	 * 过滤
	 * 按照指定的条件,对数据流里面的数据进行过滤
	 */
	@Test
	public void transformaction_Filter()
	{
		/* 准备一个容器 */
		List<Integer> intList = Arrays.asList(100,2,38,12,50,87);
		/* 准备一个Stream */
		Stream<Integer> souStream = intList.stream() ; 
		/* 过滤 
		 * java.util.function.Predicate<T>
		 * boolean test(T t);
		 * 
		 * 只有一行代码,return可以省略
		 * */
		Stream<Integer> filterStream = souStream.filter( (t) -> t > 50);
		/* 循环数据
		 * java.util.function.Consumer
		 * void accept(T t);
		 * 
		 * forEach:action算子
		 *  */
		filterStream.forEach( t -> System.out.println("==Stream循环==" + t));
		/* 关闭 */
		souStream.close();
	}
	
	/**
	 * 过滤
	 */
	@Test
	public void transformaction_Filter_Base()
	{
		/* 准备一个容器 */
		List<Integer> intList = Arrays.asList(100,2,38,12,50,87);
		/* 准备一个Stream */
		Stream<Integer> souStream = intList.stream() ;
		/* 过滤算子 */
		Stream<Integer> filterStream = souStream.filter( new Predicate<Integer>()
		{
			@Override
			public boolean test(Integer t)
			{
				System.out.println("=filter==test=" + t);
				return t > 50;
			}
		} );
		filterStream.forEach( new Consumer<Integer>()
		{
			@Override
			public void accept(Integer t)
			{
				System.out.println("==循环==" + t);
			}
		} );
		/* 关闭 */
		souStream.close();
	}
	
	/**
	 * map算子
	 * 按照指定的条件,对数据流里面的数据进行处理(加工)
	 */
	@Test
	public void transformaction_Map()
	{
		/* 准备一个容器 */
		List<Integer> intList = Arrays.asList(100,2,38,12,50,87);
		/* 准备一个Stream */
		Stream<Integer> souStream = null;
		try
		{
			souStream = intList.stream(); 
			
			/* map算子;要把输入参数,经过一个方法变成另外一个参数;(处理参数)
			 * java.util.function.Function<T, R>
			 * R apply(T t);
			 * 
			 * 需求:要把这里面的整数,都加一个字符串
			 *  */
			Stream<String> mapStream = souStream.map( (t) -> t + "==我变化了");
			
			/* 循环数据
			 * java.util.function.Consumer
			 * void accept(T t);
			 * 
			 * forEach:action算子
			 *  */
			mapStream.forEach( t -> System.out.println("==Stream循环==" + t));
		} catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally
		{
			if(souStream != null)
			{
				souStream.close();
				souStream = null ; 
			}
		}
	}
	
	/**
	 * FlatMap算子
	 * 它会对数据流里面的数据大小有要求
	 */
	@Test
	public void transformaction_FlatMap()
	{
		/* 准备一个容器 */
		List<String> strList = Arrays.asList("ab","cd","ef","test-hello-hadoop");
		/* 准备一个Stream */
		Stream<String> souStream = null;
		try
		{
			souStream = strList.stream(); 
			
			/* map算子;要把输入参数,经过一个方法变成另外一个参数;(处理参数)
			 * java.util.function.Function<T, R>
			 * R apply(T t);
			 * 
			 * 需求:要把这里面的整数,都加一个字符串
			 * 
			 * map的参数:    Function<? super T, ? extends R> mapper;R木有要求
			 * flatMap的参数:Function<? super T, ? extends Stream<? extends R>> mapper;R要求必须是Stream;
			 *  */
			Stream<String> flatMapStream = souStream.flatMap( t -> 
			{
				/* 把字符串根据-拆分开 */
				String[] splitList = t.split("-");
				/* 返回值还是Stream这里面放的是字符串 */
				List<String> tempList = Arrays.asList(splitList);
				return tempList.stream() ; 
			});
			
			/* 循环数据
			 * java.util.function.Consumer
			 * void accept(T t);
			 * 
			 * forEach:action算子
			 *  */
			flatMapStream.forEach( t -> System.out.println("==Stream循环==" + t));
		} catch (Exception e)
		{
			e.printStackTrace();
		} finally
		{
			if(souStream != null)
			{
				souStream.close();
				souStream = null ; 
			}
		}
	}
	
	/**
	 * FlatMap算子
	 * 它会对数据流里面的数据大小有要求
	 */
	@Test
	public void transformaction_other()
	{
		/* 准备一个容器 */
		List<Integer> intList = Arrays.asList(100,2,50,50,50,87);
		/* 准备一个Stream */
		Stream<Integer> souStream = null;
		try
		{
			souStream = intList.stream(); 
			/*
			 * distinct:去重
			 * */
			//Stream<Integer> stream = souStream.distinct();
			/* 取前几条记录 */
			//Stream<Integer> stream = souStream.limit(2);
			/* 跳过前n条数据 */
			//Stream<Integer> stream = souStream.skip(2);
			/* 排序:默认升序 */
			//Stream<Integer> stream = souStream.sorted();
			/* java.util.Comparator<T>:
			 * int compare(T o1, T o2);
			 *  */
			//Stream<Integer> stream = souStream.sorted( (t1,t2) -> -(t1 - t2) );
			Stream<Integer> stream = souStream.unordered();
			
			/* 循环数据
			 * java.util.function.Consumer
			 * void accept(T t);
			 * 
			 * forEach:action算子
			 *  */
			stream.forEach( t -> System.out.println("==Stream循环==" + t));
		} catch (Exception e)
		{
			e.printStackTrace();
		} finally
		{
			if(souStream != null)
			{
				souStream.close();
				souStream = null ; 
			}
		}
	}
}

2.action算子

   reduce图

在这里插入图片描述

package com.jinghangzz.jdk_new.stream;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

import org.junit.Test;

/**
 * 全是对一些action算子的测试
 * @author TeaBig
 *
 */
public class DataStreamAction
{
	/**
	 * 数据流测试的基本代码
	 */
	@Test
	public void base()
	{
		/* 准备一个List */
		List<Integer> intList = Arrays.asList(100,2,38,12,50,87);
		/* 准备一个Stream */
		Stream<Integer> stream = intList.stream() ; 
		try
		{
			/* 循环 */
			stream.forEach( t -> System.out.println("==循环==" + t));
		}catch(Exception e)
		{
			if(stream != null)
			{
				/* 关闭 */
				stream.close();
				stream = null ; 
			}
		}
	}
	
	/**
	 * 数据流测试的基本代码
	 * 数据流,只能碰到一个action算子
	 */
	@Test
	public void other()
	{
		/* 准备一个List */
		List<Integer> intList = Arrays.asList(1,2,3,4,5);
		/* 准备一个Stream */
		Stream<Integer> stream = intList.stream() ; 
		try
		{
			/* 把流里面的数据变成数组 */
//			Object[] arrays = stream.toArray();
//			System.out.println("==toString==>" + Arrays.toString(arrays));
			/* 数据的数量 */
//			long count = stream.count() ; 
//			System.out.println("==count==>" + count);
			/* 查询每一个元素 */
//			Optional<Integer> findFirst = stream.findFirst();
//			System.out.println("==findFirst==>" + findFirst.get());
			/* 获取到迭代器 */
//			for (Iterator<Integer> iterator = stream.iterator(); iterator.hasNext();)
//			{
//				Integer intValue = (Integer) iterator.next();
//				System.out.println("==循环==" + intValue);
//			}
			
			/* 获取最大值
			 * 先排序:(不管是升序还是降序,他始终认的是第一个)
			 *  */
//			Optional<Integer> maxOption = stream.max( (t1,t2) -> t1 - t2);
//			System.out.println("==max=>" + maxOption.get());
			/* 获取最小值 */
//			Optional<Integer> minOption = stream.min( (t1,t2) -> t2 - t1);
//			System.out.println("==min=>" + minOption.get());
			
			/* 缩减
			 * 参数是:java.util.function.BinaryOperator<T>;得找有抽象方法的接口:
			 * java.util.function.BiFunction<T, U, R> 
			 * 抽象方法是:R apply(T t, U u);
			 * 泛型T,U是输入参数,R是输出参数
			 *  */
			Optional<Integer> reduce = stream.reduce( (t1,t2) -> t1 + t2);
			System.out.println("==reduce=>" + reduce.get());
		}catch(Exception e)
		{
			if(stream != null)
			{
				/* 关闭 */
				stream.close();
				stream = null ; 
			}
		}
	}
}

5.总结

    5.1.关联源码

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值