首页 > 其他 > 详细

函数式编程

时间:2019-12-16 17:58:27      阅读:99      评论:0      收藏:0      [点我收藏+]

函数式编程语法

()->{}

()入参,可以是(i),(a,b)等等

{}函数体。

函数式编程接口

函数式编程接口都只有一个抽象方法,因此编译器会先将这段函数编译,并将其当做抽象方法的实现,所以=”后面的函数体可以看成是accept函数的实现。

Consumer接口

 

@FunctionalInterface
public interface Consumer<T> {


    void accept(T t);


    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

 

accept方法

 

public class Function {
  public static void main(String[] args) {
    /*传统写法*/
    Consumer<Integer> con = new Consumer<Integer>() {
          @Override
          public void accept(Integer integer) {
            System.out.println(integer);
          }
        };
    con.accept(0);

    /*函数式编程  写法一*/
    Consumer<Integer> con_1 = (i) -> {System.out.println(i);};
    con_1.accept(1);

    /*函数式编程  写法二*/
    Consumer<Integer> con_2 = (i) -> System.out.println(i);

//如果只有一个语句,可以省略{}

con_2.accept(2);

    /*函数式编程  写法三*/
    Consumer<Integer> con_3 = System.out::println;  

//针对入参,调用pringln方法打印
    con_3.accept(3);
  }
}

andThen方法

指定当前consumer调用之后再让其他comsumer调用

/*定义第一个Consumer*/
Consumer<Integer> consumer1 = (param) -> System.out.println(param);
/*定义第Consumer*/

Consumer<Integer> consumer2 = (param) -> System.out.println(param * param);
/*consumer1可以连续的调用自己, 打印出 3 3 3*/

consumer1.andThen(consumer1).andThen(consumer1).accept(3);
/*consumer1可以调用自己后调用consumer2,打印出3 3 9*/
consumer1.andThen(consumer1).andThen(consumer2).accept(3);

 

注意:当一个Consumer接口调用另外一个Consumer对象时两个Counsumer对象的泛型必须一致。

Function接口

接收一个参数并生成结果,所以该函数是有入参和返回的。

@FunctionalInterface
public interface Function<T, R> {

    R apply(T t);

    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

apply 方法

Function<Integer, Integer> function = new Function<Integer, Integer>() {
       @Override
       public Integer apply(Integer integer) {
           return null;
       }
   };

 

Function<Integer, Integer> function_1 = i -> i+1;
System.out.println( function_1.apply(2) );     //输出3

 

Function编程接口有两个泛型Function<T, R>T表示:函数的输入类型,R表示:函数的输出类型。

compose方法

Function<Integer, Integer> fun = res -> res + 1;
Function<Integer, Integer> fun1 = res -> res * 10;
Integer composeValue = fun.compose(fun1).apply(2);
System.out.println(composeValue);   //输出21

 

fun在收到2之后,先将2交给fun1处理,之后再自己处理。

andThen方法(同上consumer

Function<Integer, Integer> fun = res -> res + 1;
Function<Integer, Integer> fun1 = res -> res * 10;
Integer andThenValue = fun.andThen(fun1).apply(3);
System.out.println(andThenValue);   //输出40

identity方法

将入参直接输出

System.out.println(Function.identity().apply("总分"));//输出:总分

 

Predicate接口

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

test方法

自定义函数体,用于判断

Predicate<String> pre = res -> res.equals("1234");
boolean rest = pre.test("1234");
System.out.println(rest); //输出true

add方法

一个个执行

Predicate<String> pre = res -> res.equals("1234");
Predicate<String> pre1 = res -> res.equals("1234");
boolean rest = pre.and(pre1).test("1234");
System.out.println(rest);   //打印:true
boolean rest1 = pre.and(pre1).test("12341");
System.out.println(rest1);  //打印:false

negate方法

结果反转

default Predicate<T> negate() {
    return (t) -> !test(t);
}

 

Predicate<String> pre = res -> res.equals("1234");
boolean rest = pre.negate().test("1234");
System.out.println(rest);   //打印:false

 

or方法

只要有一个为true则为true

Predicate<String> pre = res -> res.equals("1234");
Predicate<String> pre1 = res -> res.equals("12341");
boolean rest = pre.or(pre1).test("12341");
System.out.println(rest); //打印:true

isEqual方法

判断是否相等

System.out.println(Predicate.isEqual("12345").test("12345"));//打印:true

 

Stream

通过Stream以及Optional两个类,可以进一步利用函数式接口来简化代码。

Stream可以对多个元素进行一系列的操作,也可以支持对某些操作进行并发处理。

Stream创建

方式一:list.stream()

List<String> list = Arrays.asList("a", "b", "c", "d");
Stream listStream = list.stream();    //获取串行Stream对象
Stream parallelListStream = list.parallelStream(); //获取并行Stream对象

方式二:Stream.of

Stream s1 = Stream.of("a", "b", "c", "d");

Stream使用

List<String> list = Arrays.asList("test", "t1", "t2", "teeeee", "aaaa");

filter

过滤stream中的元素,并将过滤的结果返回。

Stream<T> filter(Predicate<? super T> predicate);

示例:过滤包含te”的元素

list = list.stream()

.filter(n -> n.contains("te"))

.collect(Collectors.toList());  //list[test, teeeee]

map

元素一对一转换

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

示例:每个元素后面拼接.txt

list =  list.stream()

.map(n -> n.concat(".txt"))

.collect(Collectors.toList());

//list[test.txt, t1.txt, t2.txt, teeeee.txt, aaaa.txt]

flatMap

元素一对多转换

示例:各个元素拆分成单个字母

list =  list.stream()

.flatMap(n -> Stream.of(n.split("")))

.collect(Collectors.toList());

//list[t, e, s, t, t, 1, t, 2, t, e, e, e, e, e, a, a, a, a]

distinct

去重

list = list.stream()

.flatMap(s -> Stream.of(s.split("")))

.distinct()

.collect(Collectors.toList()); // list[t, e, s, 1, 2, a]

Sorted

排序

list = list.stream()

.flatMap(s -> Stream.of(s.split(""))).

distinct()

.sorted().

collect(Collectors.toList()); // list[1, 2, a, e, s, t]

 

Optional

用于简化java中对空值的判断处理,以防止空指针异常。

 

private final T value;

Optional的创建

方式一

Optional o = Optional.of("test");

方式二

Optional.ofNullable()//构建一个optional对象,入参可以是空值

 

Optional使用

ifPresent

判断结果不为空

 

/*传统做法*/
  String s = test();
  if (null != s) System.out.println(s);


   /*Optional做法*/
  Optional<String> s = Optional.ofNullable(test());
  s.ifPresent(System.out::println);

 

orElse

变量为空时,提供默认值


/*传统做法*/
if (null == s)  s = "test";
System.out.println(s);


/*Optional做法*/
Optional<String> o = Optional.ofNullable(s);
System.out.println(o.orElse("test"));

orElseThrow

变量为空,抛异常

 

/*传统做法*/
if (null == s)  throw new Exception("test");
System.out.println(s);


/*Optional做法*/
Optional<String> o = Optional.ofNullable(s);
System.out.println(o.orElseThrow(()->new Exception("test")));

 

Stream常见示例

List<User> list = Arrays.asList(new User("qq", 11), new User("ww", 22));

取集合各元素的某个属性为新的集合 -- map
List<String> nameList = list.stream()

.map(User::getName)

.collect(Collectors.toList());
 // nameList [qq, ww]

取集合各元素的某个属性,并经过一定操作,生成新的集合 -- map

List<Integer> ageList = list.stream()

.map(user -> user.getAge() + 1)

.collect(Collectors.toList());

  //ageList : [12, 23]

取集合元素的某个属性的某个特征

List<Integer> nameLengthList = list.stream().

map(User::getName).

map(String::length)

.collect(Collectors.toList());

//nameLengthList : [2, 2]

转换成一个新对象的集合,并输出新对象

List<Person> personList = list.stream()

.map(user -> {
    Person person = new Person(user.getName(), user.getAge());
    return person;
})

.collect(Collectors.toList());


personList.stream()

.forEach(person -> System.out.println(person.name+" "+person.age));

针对各元素某个属性计算

/*写法一*/

int ageTotal = 0;

ageTotal = list.stream()

.map(User::getAge)

.reduce(ageTotal , (a,b)-> a+b);

//ageTotal = 33

/*写法*/

Optional<Integer> ageTotal = list.stream()

.map(User::getAge)

.reduce((a, b) -> a + b);

//ageTotal .get() = 33

求某个元素某属性的最大值

Optional<Integer> max = list.stream()

.map(User::getAge)

.reduce(Integer::max);

//max = 22

数值流

 

java8中新增了三个原始类型流(IntStream、DoubleStream、LongStream)

sum()/max()/average()/count()

求和

int sum = list.stream().mapToInt(User::getAge).sum();// sum = 33

 

生产1-100之间的数字

IntStream intStream = IntStream.rangeClosed(1, 100);

 

1-100之间偶数个数

long count = IntStream.rangeClosed(1,100).filter(i->i%2==0).count();

//count = 50

 

创建流

Stream.of

Stream<String> str =  Stream.of("i","love","this","game");
str.map(String::toUpperCase).forEach(System.out::println);

Arrays.stream

int[] num = {2,5,9,8,6};
IntStream intStream = Arrays.stream(num);
int sum = intStream.sum(); //求和

函数生成 -- 0开始后面10各数求和

Optional<Integer> optional =  Stream.iterate(0, i -> i+1)

.limit(10)

.reduce((a, b)->a+b);

// optional.get() = 45

函数式编程

原文:https://www.cnblogs.com/xujiangjiang/p/12050191.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!