函数式接口及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);
}
}