java8内部调用无法引用值的问题

问题:Variable used in lambda expression should be final or effectively final

在这里插入图片描述
具体原因:
这段代码试图将 20 赋给一个局部变量,它无法通过编译,但绝非编写错误。
这实际上是语言的设计者有意为之,用以鼓励用户使用 Lambda 表达式获取值而不是变量。
获取值使用户更容易写出没有副作用的代码。
当我们在使用lambda表达式进行函数式编程时候,如何赋值局部变量是不允许的产生这样的原因是因为,lambda表达式是分为及早求值,惰性求值方法俩种方式,因为函数本身就是属于声明式类这样的方式,大大限制了函数内部的拓展使用。
如果一定要使用难免会加大程序的难度和使用,有问题后不易排查,当然这样的问题也不是没有办法,小杨告诉大家方法去处理。

实体类代码:
public static class TestJava8 {

    private int id;
    private String name;
    private int age;
    private int type;

    public TestJava8(int id, String name, int age, int type) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.type = type;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }
}

使用代码:
//方法2参数
public static List result;

//方法1 参数
public List<TestJava8> result1;

@Test
public  void main() {
    //1 实际业务过滤返回的业务数据
    TestJava8 testJava81 = new TestJava8(1, "张三", 20, 1);
    TestJava8 testJava82 = new TestJava8(2, "李四", 30, 2);
    List<TestJava8> list = new ArrayList<>();
    list.add(testJava81);
    list.add(testJava82);

    AtomicReference<List<TestJava8>> listAtomicReference = new AtomicReference<>();
    //2 过滤业务数据操作列入对接第三方平台去获取用户类型数据
    list.stream().forEach(m -> {
        //3 业务方法使用
        TestJava8 testJava83 = new TestJava8(4, "王二", 30, 3);
        TestJava8 testJava84 = new TestJava8(5, "张兰", 50, 4);
        List<TestJava8> fliterList = new ArrayList<>();
        fliterList.add(testJava83);
        fliterList.add(testJava84);
        //方法1使用
        getTestJava8List(fliterList);
        //方法2 使用
        DataUtils.setResult(fliterList);
        //方法3 使用
        listAtomicReference.set(fliterList);
        //方式4分布式缓存set

    });




    System.out.print("方法一获取:" + JSON.toJSONString(result1));
    System.out.print("方法二获取:" + JSON.toJSONString(DataUtils.getResult()));
    System.out.print("方法三获取:" + JSON.toJSONString(listAtomicReference.get()));


}

public static List<TestJava8> getResult() {
    return result;
}

public static void setResult(List<TestJava8> result) {
    DataUtils.result = result;
}

/**
 * 方法一 使用获取
 * @param list
 * @return
 */
public List<TestJava8> getTestJava8List(List<TestJava8> list) {
    result1 = list;
    return result1;
}

解决方法一:

编写方法去接收,通过对象属性赋值的特性。
//定一一个集合
public List result;
/**
* 定义本地方法返回
* @param list
* @return
*/
public List getTestJava8List(List list) {
this.result =list;
return result;
}

解决方法二:定静态属性值

静态可以缓存到常量池里面,所以有一定缓存时间,其实这种就是jvm的本地缓存
public static List result;

public static List<TestJava8> getResult() {
    return result;
}

public static void setResult(List<TestJava8> result) {
    DataUtils.result = result;
}

获取:
            //2 过滤业务数据操作列入对接第三方平台去获取用户类型数据
        list.stream().forEach(m -> {
            //3 业务方法使用
            TestJava8 testJava83 = new TestJava8(4, "王二", 30, 3);
            TestJava8 testJava84 = new TestJava8(5, "张兰", 50, 4);
            List<TestJava8> fliterList = new ArrayList<>();
            fliterList.add(testJava83);
            fliterList.add(testJava84);
            DataUtils.setResult(fliterList);
        });

使用:
DataUtils.getResult();

解决方法三:通过cas无锁的机制,内存交换原子操作AtomicReference 通过这个存入数据,既能解决当前的问题,还能保证线程的数据安全问题,通常是用这个。

使用方式:
AtomicReference<List> listAtomicReference = new AtomicReference<>();
//2 过滤业务数据操作列入对接第三方平台去获取用户类型数据
list.stream().forEach(m -> {
//3 业务方法使用
TestJava8 testJava83 = new TestJava8(4, “王二”, 30, 3);
TestJava8 testJava84 = new TestJava8(5, “张兰”, 50, 4);
List fliterList = new ArrayList<>();
fliterList.add(testJava83);
fliterList.add(testJava84);

            listAtomicReference.set(fliterList);

        });

获取: listAtomicReference.get();使用即可

解决方法四:分布式缓存

使用分布式缓存,或者第三方缓存都是能够获取到参数值的,但是对数据的一致性要求不是那么高的时候我推荐使用第三种方式,如果对数据一致性要求比较高的话就使用分布式缓存,多个服务之间共享处理,如果是比较简单单体我推荐使用第一种方式,没有很多并发和请求。

————没有与生俱来的天赋,都是后天的努力拼搏(我是小杨,谢谢你的关注和支持)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小杨互联网

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值