【java初学】函数式接口和Stream

函数式接口和Stream

1. 函数式接口
1.1 函数式接口概述
利用接口操作语法格式,对于方法的声明作出二次封装!!!
	方法声明:
		权限修饰符 是否静态 返回值类型 方法名(形式参数列表);
	对于接口而言
		返回值类型 方法名(形式参数列表);
	在使用lambda表达式的过程中
		方法名有个锤子用啊???
		·关注内容就是返回值,一个形式参数列表
1.2 常用函数式接口
1. 消费式接口
	方法是消耗一个参数,但是没有返回值
	interface Consumer<T> {
		void accept(T t);
	}

2. 生产者接口
	方法不需要参数,但是存在返回值数据
	Interface Supplier<T> {
		T get();
	}

3. 转换数据类型接口
	指定参数类型,指定返回值类型,将参数转换成对应指定数据类型
	Interface Function<T,R>  {
		R apply(T t);
	}

4. 判断接口
	判断接口,指定数据类型通过当前test方法判断,满足要求返回true,不满足返回false 类似于filter
	Interface Predicate<T> {
		boolean test(T t);
	}

5. 比较器接口
	比较器接口
	interface Comparator<T> {
		int compare(T o1, T o2);
	}
	
	以上所有接口都有对应的@FuntionalInterface 注解约束,当前接口中有且只允许存在一个未完成方法(abstract方法).
1.3 比较器函数式接口
回顾一个知识点:
	你还记得Arrays? sort方法?
	Arrays.sort(T[] t, Comparator<T> com);
package com.qfedu.a_funtion;

import java.util.Arrays;
import java.util.Comparator;

public class Demo1 {
	public static void main(String[] args) {
		SinglePerson sp1 = new SinglePerson("老王", 66, '男');
		SinglePerson sp2 = new SinglePerson("大哥", 18, '女');
		SinglePerson sp3 = new SinglePerson("鹏鹏", 16, '男');
		SinglePerson sp4 = new SinglePerson("张三", 66, '男');
		SinglePerson sp5 = new SinglePerson("李四", 46, '男');
		SinglePerson sp6 = new SinglePerson("王五", 56, '男');
		SinglePerson sp7 = new SinglePerson("赵四儿", 36, '男');
		
		SinglePerson[] arr = {
			sp1, sp2, sp3, sp4, sp5, sp6, sp7	
		};
		
		Arrays.sort(arr, new Comparator<SinglePerson>() {
			@Override
			public int compare(SinglePerson o1, SinglePerson o2) {
				return o2.getAge() - o1.getAge();
			}
		});
		
		
		Arrays.sort(arr, (p1, p2) -> p2.getAge() - p1.getAge());
		
		for (SinglePerson singlePerson : arr) {
			System.out.println(singlePerson);
		}
	}
}
1.4 消费函数式接口 Consumer
消费式接口
	方法是消耗一个参数,但是没有返回值
	interface Consumer<T> {
		void accept(T t);
	}
package com.qfedu.a_funtion;

import java.util.function.Consumer;

/**
 * 消费函数式接口
 * 		Consumer接口是封装了一个无返回值有一个参数的方法。
 * @author Anonymous
 *
 */
public class Demo2 {
	public static void main(String[] args) {
		
		String str = "消费接口的调用";
		
		test(str, new Consumer<String>() {

			@Override
			public void accept(String t) {
				System.out.println(t);
			}
		});
		
		test(str, (s) -> {
			System.out.println("字符串长度:" + s.length());
		});
	}
	
	/**
	 * 当前方法带有一个消费接口,需要完成一个有参数无返回值方法,当前接口泛型要求String类型
	 * 
	 * @param str String类型
	 * @param c Consumer消费接口
	 */
	public static void test(String str, Consumer<String> c) {
		c.accept(str);
	}
} 
1.5 生产者接口 Supplier
生产者接口
	方法不需要参数,但是存在返回值数据
	Interface Supplier<T> {
		T get();
	}
package com.qfedu.a_funtion;

/*
生产者接口
	方法不需要参数,但是存在返回值数据
	Interface Supplier<T> {
		T get();
	}
 */

import java.util.function.Supplier;

public class Demo3 {
	public static void main(String[] args) {
		Integer[] arr = {1, 3, 5, 17, 9, 2, 4, 6, 8, 10};
		
		Integer max = getMax(arr, new Supplier<Integer>() {

			@Override
			public Integer get() {
				int max = arr[0];
				for (int i = 1; i < arr.length; i++) {
					if (max < arr[i]) {
						max = arr[i];
					}
				}
				
				return max;
			}
		});
		
		Integer max2 = getMax(arr, () -> {
			int max1 = arr[0];
			for (int i = 1; i < arr.length; i++) {
				if (max1 < arr[i]) {
					max1 = arr[i];
				}
			}
			
			return max1;
		});
		
		SinglePerson sp1 = new SinglePerson("老王", 66, '男');
		SinglePerson sp2 = new SinglePerson("大哥", 18, '女');
		SinglePerson sp3 = new SinglePerson("鹏鹏", 16, '男');
		SinglePerson sp4 = new SinglePerson("张三", 66, '男');
		SinglePerson sp5 = new SinglePerson("李四", 46, '男');
		SinglePerson sp6 = new SinglePerson("王五", 56, '男');
		SinglePerson sp7 = new SinglePerson("赵四儿", 36, '男');
		
		SinglePerson[] spArr = {
			sp1, sp2, sp3, sp4, sp5, sp6, sp7	
		};
		
		SinglePerson max3 = getMax(spArr, () -> {
			SinglePerson sp = spArr[0];
			
			for (int i = 1; i < spArr.length; i++) {
				if (sp.getAge() < spArr[i].getAge()) {
					sp = spArr[i];
				}
			}
			
			return sp;
		});
		
		System.out.println(max3);
	}
	
	/**
	 * 找出指定数据类型数组中的最大值
	 * 
	 * @param <T> 反正占位符
	 * @param t 指定数据类型数组
	 * @param s 生产者接口
	 * @return 对应数据类型的最大值
	 */
	public static <T> T getMax(T[] t, Supplier<T> s) {
		return s.get();
	}
}
1.6 转换数据类型接口 Function
转换数据类型接口
	指定参数类型,指定返回值类型,将参数转换成对应指定数据类型
	Interface Function<T,R>  {
		R apply(T t);
	}
package com.qfedu.a_funtion;

import java.util.function.Function;

/**
 * 转换接口
 * @author Anonymous
 *
 */
public class Demo4 {
	public static void main(String[] args) {
		String str = "骚磊,106,男";
		
		SinglePerson person = change(str, new Function<String, SinglePerson>() {

			@Override
			public SinglePerson apply(String t) {
				String[] split = t.split(",");
			
				String name = split[0];
				int age = Integer.parseInt(split[1]);
				char gender = split[2].charAt(0);
				
				return new SinglePerson(name, age, gender);
			}
		});
		
		SinglePerson person2 = change(str, (s) -> {
			String[] split = s.split(",");
			
			String name = split[0];
			int age = Integer.parseInt(split[1]);
			char gender = split[2].charAt(0);
			
			return new SinglePerson(name, age, gender);
		});
		
		System.out.println(person2);
	}
	
	/**
	 * 讲字符串内容转换成SinglePerson类型
	 * 
	 * @param str 数据字符串
	 * @param fun 转换接口
	 * @return SinglePerson类型
	 */
	public static SinglePerson change(String str, Function<String, SinglePerson> fun) {
		return fun.apply(str);
	}
}
1.7 判断接口 Predicate
判断接口,指定数据类型通过当前test方法判断,满足要求返回true,不满足返回false 类似于filter
	Interface Predicate<T> {
		boolean test(T t);
	}
package com.qfedu.a_funtion;

import java.security.Permissions;
import java.util.ArrayList;
import java.util.function.Predicate;

public class Demo5 {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();
		
		list.add("手撕大骨头");
		list.add("小鸡炖蘑菇");
		list.add("铁锅炖大鹅");
		list.add("红烧肉");
		list.add("红烧排骨");
		list.add("糖醋里脊");
		list.add("宫保鸡丁");
		list.add("辣子鸡丁");
		list.add("清蒸哈什蚂");
		list.add("西湖牛肉羹");
		list.add("米酒小圆子");
		
		/*
		list.removeIf(new Predicate<String>() {

			@Override
			public boolean test(String t) {
				return t.contains("哈什蚂");
			}
		});
		
		list.removeIf(s -> s.length() > 4);
		*/
		list.stream().skip(3).forEach(System.out::println);
	}
}
2. Stream流式操作
2.1 先体验后讲解
package com.qfedu.b_stream;

import java.util.ArrayList;

/*
 * 1. 要求获取字符串长度大于3的内容
 * 2. 跳过前5个数据
 * 3. 最后保存数据中带有"鸡丁"
 * 4. 展示
 */
public class Demo2 {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();

		list.add("手撕大骨头");
		list.add("小鸡炖蘑菇");
		list.add("铁锅炖大鹅");
		list.add("红烧肉");
		list.add("红烧排骨");
		list.add("糖醋里脊");
		list.add("宫保鸡丁");
		list.add("辣子鸡丁");
		list.add("清蒸哈什蚂");
		list.add("西湖牛肉羹");
		list.add("米酒小圆子");
		
		// 流水线操作!!!
		list.stream()
			.filter(s -> s.length() > 3)
			.skip(5)
			.filter(s -> s.contains("鸡丁"))
			.forEach(System.out::println);
	}
}
2.2 Stream流式思想
流水线!!!

在这里插入图片描述

2.3 Stream流对象
Stream流对象
	对于集合提供了一套完备的使用方法,并且提供了获取Stream类对象的方法。

Collection接口中的默认方法。
default Stream<E> stream() {
	return StreamSupport.stream(spliterator(), false);
}

常用方法:
	Stream<T> filter(Predicate<? super T> predicate);
		过滤方法,需要的参数是Predicate过滤器接口
			boolean test(T t);
	
	<R> Stream<R> map(Function<? super T, ? extends R> mapper);
		映射方法,将当前Stream流中的T类型数据转换为R类型数据,并且返回的Stream
		类对象对应的是R类型数据
			R apply(T t);
		举例:
			T 土豆
			R 薯片
	
	Stream<T> sorted(Comparator<? super T> comparator);
		排序方法,要求传入的参数是Comparator接口
        	int compare(T o1, T o2);
    
    Stream<T> limit(long maxSize);
    	限制方法 maxSize最大值,演示看效果
    
    Stream<T> skip(long n);
    	跳过方法, n表示跳过的数据个数
    
    void forEach(Consumer<? super T> action);
    	forEach 遍历操作使用 需要的接口是Consumer消费者接口
    	终止方法!!!返回值类型不是Streamlong count();
    	返回当前Stream类中还剩余多少数据
    	终止方法!!!返回值类型不是Stream
2.4 filter 过滤
package com.qfedu.b_stream;

import java.util.ArrayList;
import java.util.stream.Stream;

/*
 * 过滤
 */
public class Demo3 {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();

		list.add("冰箱 美的");
		list.add("油烟机 老板");
		list.add("洗衣机 美的");
		list.add("开关面板 西门子");
		list.add("瓷砖 东鹏");
		list.add("卧室门 Tata");
		list.add("锁 德施曼");

		/*
		 * Stream<String> stream = list.stream(); Stream<String> filter =
		 * stream.filter(s -> s.length() > 6); filter.forEach(System.out::println);
		 */
		/*
		 * Stream流处理过程中,对于原始数据是没有任何印象的,是在操作Stream流缓存数据
		 */
		list.stream()
			.filter(s -> s.length() > 6)
			.forEach(System.out::println);

		System.out.println(list);
	}
}
2.5 Map映射
package com.qfedu.b_stream;

import java.util.ArrayList;

public class Demo4 {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();
		
		list.add("1,骚磊,16");
		list.add("2,大哥,18");
		list.add("3,老黑,66");
		list.add("4,帅栋,36");
		list.add("5,杨仔,26");
		list.add("6,博哥,56");
		list.add("7,鹏鹏,6");
		list.add("8,骚杰,106");
		list.add("9,苟磊,16");
		
		list.stream()
			.map(s -> {
				String[] split = s.split(",");
				
				int id = Integer.parseInt(split[0]);
				String name = split[1];
				int age = Integer.parseInt(split[2]);
				
				return new Person(id, name, age);
			})
			.forEach(System.out::println);
	}
}
2.6 sorted排序方法
package com.qfedu.b_stream;

import java.util.ArrayList;

public class Demo5 {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();
		
		list.add("1,骚磊,16");
		list.add("2,大哥,18");
		list.add("3,老黑,66");
		list.add("4,帅栋,36");
		list.add("5,杨仔,26");
		list.add("6,博哥,56");
		list.add("7,鹏鹏,6");
		list.add("8,骚杰,106");
		list.add("9,苟磊,16");
		
		list.stream()
			.map(s -> {
				String[] split = s.split(",");
				
				int id = Integer.parseInt(split[0]);
				String name = split[1];
				int age = Integer.parseInt(split[2]);
				
				return new Person(id, name, age);
			})
			.sorted((p1, p2) -> p2.getAge() - p1.getAge())
			.forEach(System.out::println);;
			
		list.stream()
			.map(s -> {
				String[] split = s.split(",");
				
				int id = Integer.parseInt(split[0]);
				String name = split[1];
				int age = Integer.parseInt(split[2]);
				
				return new Person(id, name, age);
			})
			// sorted() 无参数方法需要借助于当前排序数据的自然顺序,或者Comparable接口
			.sorted() 
			.forEach(System.out::println);;
	}
}
2.7 limit 和 skip
package com.qfedu.b_stream;

import java.util.ArrayList;

public class Demo6 {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();
		
		list.add("刘亦菲");
		list.add("高圆圆");
		list.add("佟丽娅");
		list.add("王祖贤");
		list.add("玛丽莲梦露");
		list.add("贾玲");
		list.add("拼多多小岳岳");
		
		list.stream()
			/*
			 * limit是限制最大个数,从0开始到maxSize
			 * limit(int maxSize)
			 */
			.limit(5)
			.forEach(System.out::println);
		
		System.out.println();
		
		list.stream()
			/*
			 * skip是跳过指定数据
			 * skip(3) 是跳过前三个
			 */
			.skip(3)
			.forEach(System.out::println);
	}	
}
2.8 foreach 和 count
终止方法!!!
	stream流运行到foreach和count终止Stream流

forEach(System.out::println);
	System.out::println 方法引用
	这里需要【引入,使用】这个方法
package com.qfedu.b_stream;

import java.util.ArrayList;

public class Demo7 {
	public static void main(String[] args) {
		
		ArrayList<String> list = new ArrayList<String>();
		
		list.add("胡歌");
		list.add("古巨基");
		list.add("彭于晏");
		list.add("金城武");
		list.add("成龙");
		list.add("张译");
		list.add("张涵予");
		list.add("吴京");
		list.add("陈道明");
		
		long count = list.stream().count();
		System.out.println(count);
		
		// Lambda表达式
		list.stream().forEach(s -> System.out.println(s));
		
		// 方法引用
		/*
		 * System.out::println 
		 * System.out 的 println方法
		 */
		list.stream().forEach(System.out::println);
		
		/*
		 * Demo7::printElement 
		 * Demo7的 printElement方法
		 */
		list.stream().forEach(Demo7::printElement);
	}
	
	/**
	 * 有参数无返回值的方法,需要的参数类型是String类型
	 * 
	 * @param s String类型
	 */
	public static void printElement(String s) {
		System.out.println(s);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值