一.简单介绍
通常当我们调用接口得到数据时需要转换一个对象成我们内部代码中定义的数据结构,
使用java8的Function和Stream‘s map可以很方便高效的完成转换。
在我们开始之前,有两个概念要了解。 第一个是一个接受一个参数并产生结果的java.util.function.Function类。
第二个是流操作类Stream,它通过提供的函数将流中的每个元素转换为另一个对象。下面的方法构造,其中T是函数的
输入类型,R是输出类型。
1 2 3 4 5 | Function<T, R> myFunction = new Function<T, R>() { public R apply(T t) { return null ; } }; |
二.示例
1 2 3 4 5 6 7 8 9 10 | //Test public class Test { private String testA; private String testB; } //MyTest public class MyTest { private Integer myTestA; private Integer myTestB; } |
三.转换成一个单独的对象
将对象转换为另一个对象的第一步是定义一个函数。 前面提到,函数将接受Test类型对象,并将返回一个MyTest的实例。
在这个方法中,我们将创建一个MyTest的新对象并设置从Test传递的值。这儿在对象之间的映射非常简单,但你可以应用
各种映射或业务规则。 调用function.apply会将函数应用于给定的参数。
1 2 3 4 5 6 7 8 9 10 11 12 | Function<Test, MyTest> testToMyTest = (t) -> { MyTest myTest = new MyTest(); myTest.setMyTestA(Integer.valueOf(t.getTestA())); myTest.setMyTestB(Integer.valueOf(t.getTestB())); return myTest; }; @Test public void convertSingleObject() { Test test = new Test( "10" , "100" ); MyTest myTest = testToMyTest.apply(test); assertEquals(myTest.getMyTestA(), myTest.getMyTestB()); } |
输出
MyTest [myTestA=10, myTestB=100]
四.转换对象集合
接下来我们转换对象集合。 随机生成一些测试数据,并在列表中调用java.util.stream.Stream()。
Java8流表示一系列可以执行一个或多个操作的元素,例如缩减和聚合操作。正如我们上面指出的那样,
我们将调用映射并传递函数来转换列表。 最后调用collect,我们将指示流返回MyTest的列表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Test public void convertCollection() { Test test1 = new Test( "10" , "100" ); Test test2 = new Test( "11" , "101" ); Test test3 = new Test( "12" , "102" ); Test test4 = new Test( "13" , "103" ); List<Test> tests = new ArrayList<Test>(); tests.add(test1); tests.add(test2); tests.add(test3); tests.add(test4); List<MyTest> myTests = tests.stream() .map(testToMyTest) .collect(Collectors.<MyTest> toList()); } |
五.总结
那我们为什么不使用标准的foreach构造。原因如下:
1.使用函数可以促进简洁的代码
2.可重用的方法(如果我们没有使用函数,我们会复制相同的逻辑来转换单个对象和ArrayList。)
3.函数式的编程思维
4.并且更容易进行单元测试