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());
}