大数据之scala_scala对比java的Lambda表达式和流式编程

在scala中有非常方便的map,filter,reduce等对集合进行一系列操作的方法
那么我们想在java中实现这些方法该怎么编写程序呢?

首先我们想想到,要对java中的集合进行功能扩展,有两种方式:
1.装饰者模式
2.继承

使用装饰者模式时,可以编写一个包装类,在包装类里写上我们想要实现的方法模型
然后在方法的参数列表中要求传入一个接口,在接口中定义一个类似于函数的标准,
具体要实现的功能,由测试类new匿名内部类的时候自己传入

为了使我们可以传入任意类型的数据,所以我们在定义参数类型时,可以使用范型,范型除了能约束集合中的数据类型之外,还能使我们的代码变得更加灵活

包装类

import java.util.ArrayList;
/**
 * 自定义一个MyList,继承ArrayList,这样MyList就拥有了ArrayList所有的功能
 * 给定MyList集合的类型和ArrayList集合类型保持一致,都为A
 * 否则遍历旧集合时,就会出现找不到类型A的问题
 */
public class MyList<A> extends ArrayList<A> {

    //定义一个map方法,参数列表中传入一个想要实现的逻辑的接口,返回的新集合可能数据类型会发生改变,所以需要再加入一个范型<B>
    //范型也可以定义在方法列表中,放在public之后,返回值类型之前,注意返回的是我们自定义的MyList集合,范型为<B>
    //这样我们在调用map方法之后,因为返回的是MyList集合,又可以继续点MyList类中的方法,形成类似流式运算的流程
    public <B> MyList<B> map(Function1<A,B> f1) {
        //创建一个新的集合
        MyList<B> nlist = new MyList<>();
        //遍历老的集合,老的集合即调用该方法时的本类的对象(this)
        for (A l : this) {
            //调用Function1中的apply方法,执行我们自定义的逻辑
            B apply = f1.apply(l);
            //将新的值放入新的集合中
            nlist.add(apply);
        }
        //返回新集合
        return nlist;
    }

    //定义一个filter方法,因为筛选过后的数据类型一般都和原数据类型相同,所以传入的类型和返回的类型都为A
    //筛选时返回的结果要么是true,要么是false,所以直接给Function1的返回类型为Boolean
    public MyList<A> filter(Function1<A,Boolean> f1){

        MyList<A> nlist = new MyList<>();
        for (A a : this) {
            Boolean apply = f1.apply(a);
            if (apply){
                nlist.add(a);
            }
        }
        return nlist;
    }

    //reduce方法,聚合前后类型都相同,所以直接一个范型就可以了
    public  A reduce(Function2<A> f2){
    //立一个falg,判断遍历集合时是否来的是第一个值
        Boolean falg = true;
     //创建一个中间值,用于叠加
        A temp = null;

        for (A a : this) {
            if (falg){
            //是第一个值,就将值给到temp,并将falg改为false
                temp=a;
                falg=false;
            }else {
             //过了第一个值之后,就可以调用接口中的apply方法,将中间值和当前值传入,
             //并执行实现该接口时传入的逻辑(将两个数相加),执行完之后,又将结果给到中间值
             //这样中间值就将所有的值都加到了它身上
                temp = f2.apply(temp, a);
            }
        }
         //最后返回叠加了所以值的中间值即可
        return temp;
    }
}

定义标准的接口

//定义两个范型,A1为传入参数类型,B1为返回值类型
public interface Function1<A1,B1> {
    B1 apply(A1 t);
}

//reduce方法需要传入两个参数,所以需要定义一个两个参数的接口
public interface Function2<A> {
    A apply(A x1,A x2);
}

测试类

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class MyListText {

    public static void main(String[] args) {

        MyList<Integer> list = new MyList();

        list.addAll(Arrays.asList(1,2,3,4,5,6,7,8,9));

        //调用方法一:匿名内部类
        Integer reduce = list.map(new Function1<Integer, Integer>() {
            @Override
            public Integer apply(Integer t) {
                return t * 10;
            }
        }).filter(new Function1<Integer, Boolean>() {
            @Override
            public Boolean apply(Integer t) {
                return t > 5;
            }
        }).reduce(new Function2<Integer>() {
            @Override
            public Integer apply(Integer x1, Integer x2) {
                return x1 + x2;
            }
        });
        System.out.println(reduce);  //450


        //调用方法二:Lambda表达式
        String reduce1 = list.filter(x -> x > 5)
        				.map(x -> "doit" + x * 10)
        				.reduce((x1, x2) -> x1 + x2);

        System.out.println(reduce1); //doit60doit70doit80doit90
	}
}

java自带的流式编程

public class MyListText {
	public static void main(String[] args) {
	   List<Integer> list = new ArrayList();
       list.addAll(Arrays.asList(1,2,3,4,5,6,7,8,9));

       //将集合中的数据变成水流状的,放入流中进行一步一步的操作,通过filter和map方法之后,返回的是一个Stream类型的数据
       Stream<Integer> stream = list.stream().filter(x -> x > 6).map(x -> x * x);
       //可以通过collect(Collectors.toList())方法将Stream类型的数据转回List
       List<Integer> collect = stream.collect(Collectors.toList());

       //reduce方法聚合后,返回的是Optional类型的数据,因为聚合后的数据可能存在也可能不存在
       Optional<Integer> reduce2 = list.stream().filter(x -> x > 6).map(x -> x * x).reduce((x1, x2) -> x1 + x2);
       //get()方法可以取出它里面的值
       Integer integer = reduce2.get();
       System.out.println(integer);  //194

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值