打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
JavaSE23-函数式接口&Stream流
1.函数式接口
1.1 函数式接口概述
概念
有且仅有一个抽象方法的接口
如何检测一个接口是不是函数式接口
@FunctionalInterface
放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败
注意事项
我们自己定义函数式接口的时候,@FunctionalInterface是可选的,就算我不写这个注解,只要保证满足函数式接口定义的条件,也照样是函数式接口。但是,建议加上该注解。
1.2 函数式接口作为方法的参数
1 public class RunnableDemo { 2 public static void main(String[] args) { 3 startRunnable(() -> { 4 System.out.println(Thread.currentThread().getName() "启动了"); 5 }); 6 } 7 8 private static void startRunnable(Runnable r) { 9 new Thread(r).start();10 }11 }
在Runnable中有如下定义
1 @FunctionalInterface 2 public interface Runnable { 3 /** 4 * When an object implementing interface {@code Runnable} is used 5 * to create a thread, starting the thread causes the object's 6 * {@code run} method to be called in that separately executing 7 * thread. 8 * <p> 9 * The general contract of the method {@code run} is that it may10 * take any action whatsoever.11 *12 * @see java.lang.Thread#run()13 */14 public abstract void run();15 }1.3 函数式接口作为方法的返回值
1 import java.sql.Connection; 2 import java.util.ArrayList; 3 import java.util.Collection; 4 import java.util.Collections; 5 import java.util.Comparator; 6 7 public class getComparetorDemo { 8 public static void main(String[] args) { 9 ArrayList<String> list = new ArrayList<>();10 list.add("aaa");11 list.add("b");12 list.add("dd");13 list.add("cccc");14 15 System.out.println("排序前:" list);16 17 Collections.sort(list,getComparetor());18 19 System.out.println("排序后:" list);20 }21 22 private static Comparator<String> getComparetor() {23 return (s1,s2) -> s1.length() - s2.length();24 }25 }1.4 常用函数式接口之Supplier
Supplier接口
Supplier接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据供我们使用。
构造方法
方法名说明
T get()按照某种实现逻辑(由Lambda表达式实现)返回一个数据
返回字符串
1 import java.util.function.Supplier; 2 3 public class SupplierDemo { 4 public static void main(String[] args) { 5 System.out.println(useSup( 6 () -> "hello world" 7 )); 8 } 9 10 private static String useSup(Supplier<String> sup) {11 return sup.get();12 }13 }
返回最大值
1 import java.util.function.Supplier; 2 3 public class SupplierDemo2 { 4 public static void main(String[] args) { 5 int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 21, 142, 11, 2241, 24}; 6 int maxValue = useSup(() -> { 7 int max = arr[0]; 8 9 for (int i = 0; i < arr.length; i ) {10 if (max < arr[i]) {11 max = arr[i];12 }13 }14 15 return max;16 });17 18 System.out.println(maxValue);19 }20 21 private static Integer useSup(Supplier<Integer> sup) {22 return sup.get();23 }24 } 1.5 常用函数式接口之Consumer
Consumer接口
Consumer接口也被称为消费型接口,它消费的数据的数据类型由泛型指定
常用方法
方法名说明
void accept(T t)对给定的参数执行此操作
default Consumer andThen(Consumer after)返回一个组合的Consumer,依次执行此操作,然后执行after操作
1 import java.util.function.Consumer; 2 3 public class ConsumerDemo { 4 public static void main(String[] args) { 5 String[] list = {"1,绿巨人","2,钢铁侠","3,美国队长"}; 6 7 printinfo(list,str -> System.out.print("序号" str.split(",")[0]),str -> System.out.println(str.split(",")[1])); 8 } 9 10 public static void printinfo(String[] list, Consumer<String> con1,Consumer<String> con2){11 for (String s : list){12 con1.andThen(con2).accept(s);13 }14 }15 }1.6 常用函数式接口之Predicate
Predicate接口
Predicate接口通常用于判断参数是否满足指定的条件
方法名说明
boolean test(T t)对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回 一个布尔值
default Predicate negate()返回一个逻辑的否定,对应逻辑非
default Predicate and(Predicate other)返回一个组合判断,对应短路与
default Predicate or(Predicate other)返回一个组合判断,对应短路或
1 import java.util.function.Predicate; 2 3 public class PredicateDemo { 4 public static void main(String[] args) { 5 boolean a = check("hello world",s -> s.length()<5); 6 System.out.println(a); 7 8 boolean b = uncheck("hello world",s -> s.length()<5); 9 System.out.println(b);10 }11 12 private static boolean check(String s , Predicate<String> pre){13 return pre.test(s);14 }15 16 private static boolean uncheck(String s , Predicate<String> pre){17 return pre.negate().test(s);18 }19 } 1.7 常用函数式接口之Function
Function接口
Function<t,r>接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值
方法名说明
R apply(T t)将此函数应用于给定的参数
default Function andThen(Function after)返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果
1 import java.util.function.Function; 2 3 public class FunctionDemo { 4 public static void main(String[] args) { 5 parseint("13729",s -> Integer.parseInt(s)); 6 } 7 8 private static void parseint(String s, Function<String,Integer> fun) { 9 int i = fun.apply(s);10 System.out.println(i);11 }12 }2.Strem流
2.1 体验Stream流
1 import java.util.ArrayList; 2 3 public class FilterDemo { 4 public static void main(String[] args) {//将姓张且名字在两个字(不含两个)以上的名字加入另一个集合 5 ArrayList<String> names = new ArrayList<>(); 6 7 names.add("张无忌"); 8 names.add("赵敏"); 9 names.add("张三丰");10 names.add("张果老");11 names.add("张国立");12 names.add("铁拐李");13 names.add("张赫");14 names.add("张飞");15 names.add("张翼德");16 names.add("刘备");17 names.add("关云长");18 names.add("曹孟德");19 names.add("吕轻侯");20 21 ArrayList<String> zhanglist = new ArrayList<>();22 23 names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() >=3).forEach(System.out::println);24 }25 }
Stream流的好处
直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为3、逐一打印
Stream流把真正的函数式编程风格引入到Java中
2.2 Stream流的常见生成方式
生成Stream流的方式
Collection体系集合
使用默认方法stream()生成流, default Stream stream()
Map体系集合
把Map转成Set集合,间接的生成流
数组
通过Stream接口的静态方法of(T... values)生成流
1 import java.util.*; 2 import java.util.stream.Stream; 3 4 public class CreateStream { 5 public static void main(String[] args) { 6 //Collection体系直接使用stream() 7 List<String> list = new ArrayList<>(); 8 Stream<String> listStream = list.stream(); 9 10 Set<String> set = new TreeSet<>();11 Stream<String> setStream = set.stream();12 //Map体系间接生成13 Map<String,Integer> map = new HashMap<>();14 Stream<String> keyStream = map.keySet().stream();15 Stream<Integer> valueStream = map.values().stream();16 17 Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();18 //数组使用Stream接口的of()19 String[] nums = {"1","2","3","4"};20 Stream<String> numStringStream = Stream.of(nums);21 Stream<Integer> numStram = Stream.of(1,2,3,4,5);22 }23 }2.3 Stream流中间操作方法
概念
中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作。
常用方法
方法名说明
Stream filter(Predicate predicate)用于对流中的数据进行过滤
Stream limit(long maxSize)返回此流中的元素组成的流,截取前指定参数个数的数据
Stream skip(long n)跳过指定参数个数的数据,返回由该流的剩余元素组成的流
static Stream concat(Stream a, Stream b)合并a和b两个流为一个流
Stream distinct()返回由该流的不同元素(根据Object.equals(Object) )组成的流
Stream sorted()返回由此流的元素组成的流,根据自然顺序排序
Stream sorted(Comparator comparator)返回由该流的元素组成的流,根据提供的Comparator进行排序
Stream map(Function mapper)返回由给定函数应用于此流的元素的结果组成的流
IntStream mapToInt(ToIntFunction mapper)返回一个IntStream其中包含将给定函数应用于此流的元素的结果
limit&skip
1 import java.util.ArrayList; 2 3 public class limitandskipDemo { 4 public static void main(String[] args) { 5 ArrayList<String> names = new ArrayList<>(); 6 7 names.add("张无忌"); 8 names.add("赵敏"); 9 names.add("张三丰");10 names.add("张果老");11 names.add("张国立");12 names.add("铁拐李");13 names.add("张赫");14 names.add("张飞");15 names.add("张翼德");16 names.add("刘备");17 names.add("关云长");18 names.add("曹孟德");19 names.add("吕轻侯");20 21 //输出前三个22 names.stream().limit(3).forEach(System.out::println);23 System.out.println("-------");24 //跳过三个然后输出25 names.stream().skip(3).forEach(System.out::println);26 System.out.println("-------");27 //跳过四个输出五个28 names.stream().skip(4).limit(5).forEach(System.out::println);29 }30 }
concat&distinct
1 import java.util.ArrayList; 2 import java.util.stream.Stream; 3 4 public class concatanddistinctDemo { 5 public static void main(String[] args) { 6 ArrayList<String> names = new ArrayList<>(); 7 names.add("张无忌"); 8 names.add("赵敏"); 9 names.add("张三丰");10 names.add("张果老");11 names.add("张国立");12 names.add("铁拐李");13 14 //截取前四个为流s115 Stream<String> s1 = names.stream().limit(4);16 //跳过前两个为流s217 Stream<String> s2 = names.stream().skip(2);18 //合并s1,s219 // Stream.concat(s1, s2).forEach(System.out::println);20 //合并并去重21 Stream.concat(s1, s2).distinct().forEach(System.out::println);22 }23 }
sort
1 import java.util.ArrayList; 2 3 public class sortDemo { 4 public static void main(String[] args) { 5 ArrayList<String> names = new ArrayList<>(); 6 names.add("张无忌"); 7 names.add("赵敏"); 8 names.add("张三丰"); 9 names.add("张果老");10 names.add("张国立");11 names.add("铁拐李");12 13 names.stream().sorted((s1,s2) -> {14 int num = s1.length()-s2.length();15 int num2 = num == 0 ? s2.compareTo(s1) : num;16 return num2;17 }).forEach(System.out::println);18 }19 }
maptoInt
1 import java.util.ArrayList; 2 3 public class maptointDemo { 4 public static void main(String[] args) { 5 ArrayList<String> nums = new ArrayList<>(); 6 nums.add("1"); 7 nums.add("10"); 8 nums.add("100"); 9 nums.add("1000");10 nums.add("10000");11 nums.add("100000");12 13 int result = nums.stream().mapToInt(Integer::parseInt).sum();14 System.out.println(result);15 }16 }
count
1 import java.util.ArrayList; 2 3 public class countDemo { 4 public static void main(String[] args) { 5 ArrayList<String> names = new ArrayList<>(); 6 7 names.add("张无忌"); 8 names.add("赵敏"); 9 names.add("张三丰");10 names.add("张果老");11 names.add("张国立");12 names.add("铁拐李");13 names.add("张赫");14 names.add("张飞");15 names.add("张翼德");16 names.add("刘备");17 names.add("关云长");18 names.add("曹孟德");19 names.add("吕轻侯");20 21 long count = names.stream().filter(s -> s.startsWith("张")).count();22 System.out.println(count);23 }24 }
练习
这里有两个集合,有6个男演员和6个女演员,要求:
男演员只要名字为3个字的前三人
女演员只要姓林的,并且不要第一个
把过滤后的男演员姓名和女演员姓名合并到一起
把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
Actor类
1 public class Actor { 2 private String name; 3 4 public Actor(String name) { 5 this.name = name; 6 } 7 8 public String getName() { 9 return name;10 }11 12 public void setName(String name) {13 this.name = name;14 }15 }
实现类
1 import java.util.ArrayList; 2 import java.util.stream.Stream; 3 4 public class ActorControl { 5 public static void main(String[] args) { 6 ArrayList<String> man = new ArrayList<>(); 7 ArrayList<String> woman = new ArrayList<>(); 8 9 man.add("刘德华");10 man.add("成龙");11 man.add("周星驰");12 man.add("周润发");13 man.add("李小龙");14 man.add("林正英");15 16 woman.add("林青霞");17 woman.add("关之琳");18 woman.add("朱茵");19 woman.add("林志玲");20 woman.add("林心如");21 woman.add("王祖贤");22 23 //男演员只要名字为3个字的前三人24 Stream<String> manStream = man.stream().filter(s -> s.length() == 3).limit(3);25 //女演员只要姓林的,并且不要第一个26 Stream<String> womanStream = woman.stream().filter(s -> s.startsWith("林")).skip(1);27 //把过滤后的男演员姓名和女演员姓名合并到一起28 Stream<String> stream = Stream.concat(manStream, womanStream);29 //把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据30 stream.map(Actor::new).forEach(s -> System.out.println(s.getName()));31 }32 }
或者更简便的写法
1 import java.util.ArrayList; 2 import java.util.stream.Stream; 3 4 public class ActorControl { 5 public static void main(String[] args) { 6 ArrayList<String> man = new ArrayList<>(); 7 ArrayList<String> woman = new ArrayList<>(); 8 9 man.add("刘德华");10 man.add("成龙");11 man.add("周星驰");12 man.add("周润发");13 man.add("李小龙");14 man.add("林正英");15 16 woman.add("林青霞");17 woman.add("关之琳");18 woman.add("朱茵");19 woman.add("林志玲");20 woman.add("林心如");21 woman.add("王祖贤");22 23 Stream.concat(man.stream().filter(s -> s.length() == 3).limit(3),woman.stream().filter(s -> s.startsWith("林")).skip(1)).map(Actor::new).forEach(s -> System.out.println(s.getName()));24 }25 }2.4 Stream流的收集操作
概念
对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中。
常用方法
方法名说明
R collect(Collector collector)把结果收集到集合中
工具类Collectors提供了具体的收集方式
方法名说明
public static Collector toList()把元素收集到List集合中
public static Collector toSet()把元素收集到Set集合中
public static Collector toMap(Function keyMapper,Function valueMapper)把元素收集到Map集合中
1 import java.util.ArrayList; 2 import java.util.List; 3 import java.util.Map; 4 import java.util.Set; 5 import java.util.stream.Collectors; 6 import java.util.stream.Stream; 7 8 public class CollectorsDemo { 9 public static void main(String[] args) {10 List<String> names = new ArrayList<>();11 names.add("张无忌");12 names.add("赵敏");13 names.add("张三丰");14 names.add("张果老");15 names.add("张国立");16 names.add("铁拐李");17 names.add("张赫");18 names.add("张飞");19 Stream<String> nameStream = names.stream().filter(s -> s.length()==3);20 List<String> threeWordsNames = nameStream.collect(Collectors.toList());21 for (String s : threeWordsNames){22 System.out.println(s);23 }24 System.out.println("------");25 Stream<String> namesStreams = names.stream().filter(s ->s.startsWith("张"));26 Set<String> threeNames = namesStreams.collect(Collectors.toSet());27 for (String sm : threeNames){28 System.out.println(sm);29 }30 System.out.println("------");31 String[] strArray = {"1,张曼玉","2,林青霞","3,朱茵"};32 Stream<String> strStream = Stream.of(strArray);33 Map<String,String> bf = strStream.collect(Collectors.toMap(s -> s.split(",")[0],s -> s.split(",")[1]));34 Set<String> keys = bf.keySet();35 for (String key : keys){36 String value = bf.get(key);37 System.out.println(value);38 }39 }40 }
来源:https://www.icode9.com/content-1-774751.html
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Java进阶 之 Stream流
Java8中的Stream,一行代码,让集合操作飞起来!
感受lambda之美
Stream流
采用java8 lambda表达式 实现 java list 交集 并集 差集 去重复并集
Java基础之Java8中map和flatMap的使用
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服