Java8新特性:函数式编程、lambda表达式

Function<T, R>转换函数

函数式接口定义:仅含有一个抽象方法的接口

@FunctionalInterface
/**
  * Applies this function to the given argument.
  *
  * @param t the function argument
  * @return the function result
  */
public interface Function<T, R> {
    R apply(T t);
}

Function<T, R>执行转换操作,T为输入参数,R为返回结果,下面利用Function函数对字符串转换成整型,并忽略不是数值型的字符:

/**
  * 此函数先过滤掉非数值型字符串
  * @param list
  * @param function
  * @return
  */
private static List<Integer> parse (List<String> list, Function<String, Integer> function) {
    List<Integer> result = new ArrayList<>();
    for(String value : list){
        if(NumberUtils.isDigits(value)){
            result.add(function.apply(value));
        }
    }
    return result;
}
/**
  * 此函数先过滤掉非数值型字符
  */
public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.addAll(Arrays.asList("a","1","2","3","4","5"));
    // 传入String类型,具体转化函数为Integer.valueOf,此处为真正的实现
    List<Integer> result = parse(list,(value) -> Integer.valueOf(value));
    System.out.println(result);
}

jdk8的特性stream().map() 将对象转换成另一个对象

此示例说明如何将staff对象列表转换为对象列表StaffPublic

//Java 8之前
package com.mkyong.java8;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class BeforeJava8 {
    
    public static void main(String[] args) {
        List<Staff> staff = Arrays.asList(
                new Staff("mkyong", 30, new BigDecimal(10000)),
                new Staff("jack", 27, new BigDecimal(20000)),
                new Staff("lawrence", 33, new BigDecimal(30000))
        );
        List<StaffPublic> result = convertToStaffPublic(staff);
        System.out.println(result);
    }

    private static List<StaffPublic> convertToStaffPublic(List<Staff> staff) {
        List<StaffPublic> result = new ArrayList<>();
        for (Staff temp : staff) {
            StaffPublic obj = new StaffPublic();
            obj.setName(temp.getName());
            obj.setAge(temp.getAge());
            if ("mkyong".equals(temp.getName())) {
                obj.setExtra("this field is for mkyong only!");
            }
            result.add(obj);
        }
        return result;
    }
}
//输出:
[
    StaffPublic{name='mkyong', age=30, extra='this field is for mkyong only!'},
    StaffPublic{name='jack', age=27, extra='null'},
    StaffPublic{name='lawrence', age=33, extra='null'}
]

//Java 8的例子。
NowJava8.java
package com.mkyong.java8;
package com.hostingcompass.web.java8;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class NowJava8 {
    public static void main(String[] args) {
        List<Staff> staff = Arrays.asList(
                new Staff("mkyong", 30, new BigDecimal(10000)),
                new Staff("jack", 27, new BigDecimal(20000)),
                new Staff("lawrence", 33, new BigDecimal(30000))
        );
	   // temp相当于staff列表其中的一个实例对象,map相当于对要操作数据的一个集合
        List<StaffPublic> result = staff.stream().map(temp -> {
            StaffPublic obj = new StaffPublic();
            obj.setName(temp.getName());
            obj.setAge(temp.getAge());
            if ("mkyong".equals(temp.getName())) {
                obj.setExtra("this field is for mkyong only!");
            }
            return obj;
        }).collect(Collectors.toList());
        System.out.println(result);
    }
}
//输出:
[
    StaffPublic{name='mkyong', age=30, extra='this field is for mkyong only!'},
    StaffPublic{name='jack', age=27, extra='null'},
    StaffPublic{name='lawrence', age=33, extra='null'}
]

Optional是一个可以包含或不可以包含非空值的容器对象

Optional有方法 isPresent() 和 get()是用来检查其包含的对象是否为空或不是, 下面这个案例涉及到Lambda表达式 方法引用,是将单词流中第一个以"L"开始单词取出,作为返回结果是一个Optional

Stream<string> names = Stream.of("Lamurudu", "Okanbi", "Oduduwa");
Optional<string> longest = names.filter(name -> name.startsWith("L")).findFirst();
longest.ifPresent(name -> {
            String s = name.toUpperCase();
            System.out.println("The longest name is "+ s);
        });

Function.identity()的含义

identity()就是Function接口的一个静态方法。
Function.identity()返回一个输出跟输入一样的Lambda表达式对象,等价于形如t -> t形式的Lambda表达式

private static void identity() {
        Stream<String> stream = Stream.of("I", "love", "you", "too");
        //stream.collect相当于把stream流中每一个元素进行处理,进行整合。
        Map<String, Integer> map = stream.collect(Collectors.toMap(Function.identity(), String::length));
        System.out.println(map);
    }
    
    输出结果为:
               {love=4, too=3, I=1, you=3}

综合例子:

public static <T, R> Map<R, Collection<T>> getMap(Collection<T> books, Function<T, R> function) {
	   // 将book对象放入map中,map实际存的键值对为(R,Collection<T>)
        Optional<Map<R, Collection<T>>> reduce = books.stream().map(book -> {
            Map<R, Collection<T>> map = new ConcurrentHashMap();
            Collection<T> c = new ArrayList<>();
            c.add(book);
            map.put(function.apply(book), c);
            return map;
        }).reduce((x, y) -> {
            // 对每一个map进行聚合操作
            R yKey = y.keySet().iterator().next();
            if (x.containsKey(yKey)) {
                // 如果存在key则更新key
                x.get(yKey).addAll(y.get(yKey));
            } else {
                // 如果不存在key则新增
                x.putAll(y);
            }
            return x;
        });
        return reduce.orElse(new ConcurrentHashMap());
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值