概念
有且仅有一个抽象方法的接口
如何检测一个接口是不是函数式接口
@FunctionalInterface
放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败
注意事项
我们自己定义函数式接口的时候,@FunctionalInterface是可选的,就算我不写这个注解,只要保证满足函数式接口定义的条件,也照样是函数式接口。但是,建议加上该注解。
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 may 10 * take any action whatsoever. 11 * 12 * @see java.lang.Thread#run() 13 */ 14 public abstract void run(); 15 }
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 }
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 }
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 }
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 }
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 }
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中
生成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 }
概念
中间操作的意思是,执行完此方法之后,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 //截取前四个为流s1 15 Stream<String> s1 = names.stream().limit(4); 16 //跳过前两个为流s2 17 Stream<String> s2 = names.stream().skip(2); 18 //合并s1,s2 19 // 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 }
概念
对数据使用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.cnblogs.com/zhiyDev/p/14086133.html