函数式接口及Stream流

  • 函数式接口
  • 函数式接口的定义
  • 常用的函数式接口(java 8提供的,java.util.function)
  • Supplier接口
  • Consumer接口
  • Predicate接口
  • Function接口
  • Stream流
  • Stream流的生成方式
  • Collection体系的结合可以使用默认方法stream()生成流
  • Map体系的集合间接生成流
  • 数组可以通过Stream接口的静态方法of(T...values)生成流
  • Stream流的中间操作
  • filter操作
  • limit & skip操作
  • concat & distinct操作
  • sorted操作
  • map操作
  • Stream流的终结操作
  • Stream流的收集操作


函数式接口


函数式接口的定义

定义:有且仅有一个抽象方法的接口

@FunctionalInterface:用来表示这是一个函数式接口,如果接口时函数式接口,编译通过;如果不是,编译失败

常用的函数式接口(java 8提供的,java.util.function)

Supplier接口

/** 
	生产型接口
	@FuctionalInterface
	public interface Supplier<T>
	代表结果供应商
	方法: T   get()
**/

public class Demo{
	public static void main(String[] args){
		String s = getString(() - >{
			return "张三";
		})
		//String s = getString(() -> "张三")
		System.out.println(s);
	}
	
	private static String getString(Supplier<String> sup){
		return sup.get();	
	}
}

Consumer接口

/**
	消费型接口
	@FunctionalInterface
	public interface Consumer<T>
	表示接受单个参数并且不返回结果的操作
	方法: void accept(T t)	对给定的参数执行此操作
		  default Consumer<T>  andThen(Consumer<? super T> after) 返回一个组成的Consumer,依次执行此操作,然后执行after操作
**/

public class Demo{
	public static void main(String[] args){
		operatorString("张三", (String s) -> {
			System.out.println(s);	
		})
		operatorString("张三", s -> System.out.println(s));
		operatorString("张三", System.out::println);
		
		operatorString("张三", s -> System.out.println(s), s -> System.out.println(new StringBuilder(s).reverse.toString()))
	}
	
	private static void operatorString(String name, Consumer<String> con){
		con.accept(name);
	}

	private static void operatorString(String name, Consumer<String> con1, Consumer<String> con2){
		//con1.accept(name);
		//con2.accept(name);
		con1.andThen(con2).accept(name);
	}
}

Predicate接口

/**
	@FucationalInterface
	public interface Predicate<T>
	表示一个参数的谓词(布尔值函数)
	方法:
		default Predicate<T>  and(Predicate<? super T> other)  返回一个组合的谓词,表示该谓词与另一个谓词的短路逻辑AND
		static <T> Predicate<T>  isEqual(Object targetRef) 返回一个谓词,根据Objects.equals(Object, Object)测试两个参数是否相等
		default Predicate<T>  negate()  返回表示此谓词的逻辑否定的谓词
		default Predicate<T>  or(Predicate<? super T> other)  返回一个组合的谓词,表示该谓词与另一个谓词的短路逻辑或
		boolean  test(T t)  在给定的参数上评估这个谓词
**/

public class Demo{
	public static void main(String[] args){
		boolean b1 = checkString("hello", (String s) -> {
			return s.length() > 8;
		})
		System.out.println(b1);

		boolean b2 = checkString("hello", s -> s.length() > 8, s -> s.length() < 15);
		System.out.println(b2);
	}
	
	private static boolean checkString(String s, Predicate<String> pre){
		return pre.test(s);
		return pre.negate().test(s);
	}

	private static boolean checkString(String s, Predicate<String> pre1, Predicate<String> pre2){
		boolean b1 = pre1.test(s);
		boolean b2 = pre2.test(s);
		boolean b = b1 && b2;
		return b;

		//return pre1.and(pre2).test(s);
		//return pre1.or(pre2).test(s);
	}
}

Function接口

/**
	@FunctionalInterface
	public interface Function<T,R>
	表示接受一个参数并产生结果
	方法:
		default <T> Function<T, V>  andThen(Function<? super R, ? extends V> after)  返回一个组合函数,首先将该函数应用于其输入,然后将after函数应用于结果
		R apply(T t)  将此函数应用于给定的参数
		default <V> Function<V, R>  compose(Function<? super V, ? extends T> before)  返回一个组合函数,首先将before函数应用于其输入,然后将此函数应用于结果
		static <T> Function<T, T>  identity()  返回一个总是返回其输入参数的函数
**/

public class Demo{
	public static void main(String[] args){
		convert("100", s -> Integer.parseInt(s));
		convert("100", Integer::parseInt);
	}
	
	private static void convert(String s, Function<String, Integer> fun){
		Integer i = fun.apply(s);
		System.out.println(s);
	}
}



Stream流


Stream流的生成方式

Collection体系的结合可以使用默认方法stream()生成流

List<String> list = new ArrayList<String>();
 
 Stream<String> listStream = list.stream();

Map体系的集合间接生成流

Map<String, Integer> map = new HashMap<String, Integer>();

Stream<String> keyStream = map.keySet().stream();

Stream<Integer> valueStream = map.values().stream();

Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();

数组可以通过Stream接口的静态方法of(T…values)生成流

String[] strArray = {"hello", "world"};

Stream<String> strArrayStream = Stream.of(strArray);

Stream流的中间操作

filter操作

/**
	Stream<T> filter(Predicate predicate):用于对流中的数据进行过滤
**/

public class Demo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();

        list.add("张三");
        list.add("李四");
        list.add("王二");
        list.add("麻子");
        list.add("张小小");

        list.stream().filter(s -> s.startsWith("张")).forEach(System.out::println);

        list.stream().filter(s -> s.length() == 3).forEach(System.out::println);

        list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(System.out::println);
    }
}

limit & skip操作

/**
	Stream<T> limit(long maxSize): 返回此流中的元素组成的流,截取前指定参数个数的数据
	Stream<T> skip(long n): 跳过指定参数个数的数据,返回由该流的剩余元素组成的流
**/

public class Demo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();

        list.add("张三");
        list.add("李四");
        list.add("王二");
        list.add("麻子");
        list.add("张小小");

        list.stream().limit(3).forEach(System.out::println);

        list.stream().skip(3).forEach(System.out::println);

        list.stream().skip(2).limit(2).forEach(System.out::println);
    }
}

concat & distinct操作

/**
	static<T> Stream<T> concat(Stream a, Stream b):合并a和b两个流为一个流
	Stream<T> distinct():返回由该流的不同元素(根据Object.equals(Object))组成的流
**/

public class Demo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();

        list.add("张三");
        list.add("李四");
        list.add("王二");
        list.add("麻子");
        list.add("张小小");

        Stream<String> s1 = list.stream().limit(3);
        Stream<String> s2 = list.stream().skip(2);

        Stream.concat(s1, s2).forEach(System.out::println);

        //去掉重复元素
        Stream.concat(s1, s2).distinct().forEach(System.out::println);
    }
}

sorted操作

/**
	Stream<T> sorted():返回由此流的元素组成的流,根据自然顺序排序
	Stream<T> sorted(Comparator comparator):返回由该流的元素组成的流,根据提供的Comparator进行排序
**/

public class Demo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();

        list.add("zhangsan");
        list.add("lisi");
        list.add("wanger");
        list.add("mazi");
        list.add("zhangxiaoxiao");

        list.stream().sorted().forEach(System.out::println);

        //按长度排序,长度相同时按默认顺序排序
        //list.stream().sorted((s1, s2) -> s1.length() - s2.length()).forEach(System.out::println);
        list.stream().sorted((s1, s2) -> {
            int num = s1.length() - s2.length();
            int num2 = num == 0 ? s1.compareTo(s2) : num;
            return num2;
        }).forEach(System.out::println);
    }
}

map操作

/**
	<R> Stream<R> map(Function mapper):返回由给定函数应用于此流的元素的结果组成的流
	IntStream mapToInt(ToIntFunction mapper):返回一个IntStream其中包含给定函数应用于此流的元素的结果
		IntStream:表示原始int流
		ToIntFunction接口中的方法	int applyAsInt(T value)
**/

public class Demo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();

        list.add("10");
        list.add("20");
        list.add("30");
        list.add("40");
        list.add("50");

        list.stream().map(Integer::parseInt).forEach(System.out::println);

        list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);

        //mapToInt中特有的方法
        int sum = list.stream().mapToInt(Integer::parseInt).sum();
        System.out.println(sum);
    }
}

Stream流的终结操作

/**
	void forEach(Consumer action):对此流的每个元素执行操作
	long count():返回此流中的元素数
**/

public class Demo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();

        list.add("张三");
        list.add("李四");
        list.add("王二");
        list.add("麻子");
        list.add("张小小");

        list.stream().forEach(System.out::println);

        long count = list.stream().filter(s -> s.startsWith("张")).count();
        System.out.println(count);
    }
}

Stream流的收集操作

/**
	对数据使用Stream流的方式操作完毕后,将流中的数据收集到集合中
	R collect(Collector collector)

	public static<T> Collector toList():把元素收集到List集合中
	public static<T> Collector toSet():把元素收集到Set集合中
	public static Collector toMap(Function keyMapper, Function valueMapper):把元素收集到Map集合中
**/

public class Demo {
    public static void main(String[] args) {
        // 收集到list集合中
        ArrayList<String> list = new ArrayList<String>();

        list.add("张三");
        list.add("李四");
        list.add("王二");
        list.add("麻子");
        list.add("张小小");

        Stream<String> listStream = list.stream().filter(s -> s.length() == 2);
        List<String> names = listStream.collect(Collectors.toList());
        for (String name : names) {
            System.out.println(name);
        }

        //收集到set集合中
        Set<Integer> set = new HashSet<Integer>();
        set.add(10);
        set.add(20);
        set.add(30);
        set.add(40);
        set.add(50);

        Stream<Integer> setStream = set.stream().filter(s -> s > 30);
        Set<Integer> ages = setStream.collect(Collectors.toSet());
        for (Integer age : ages) {
            System.out.println(age);
        }

        //收集到map集合中
        String[] strArray = {"张三,20", "李四,30", "王二,35", "麻子,40"};
        Stream<String> arrayStream = Stream.of(strArray).filter(s -> Integer.parseInt(s.split(",")[1]) > 30);
        Map<String, Integer> map = arrayStream.collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));
        Set<String> keySet = map.keySet();
        for (String key : keySet) {
            Integer value = map.get(key);
            System.out.println(key + "," + value);
        }
    }