桃园结义 , 版权所有丨如未注明 , 均为原创丨转载请注明

Java8的部分特性 “函数式编程”

桃园小编 548次浏览 0个评论 扫描二维码

     函数式编程作为一种编程规范,一切都是数学函数,函数式编程语言里也可以有对象,但通常这些对象都是恒定不变的——要么是函数参数,要么是函数返回值。

     函数式编程语言中中没有 for/next 循环,因为这些逻辑意味着有状态的改变。相替代的是,这种循环逻辑在函数式编程语言里是通过递归,把函数当成参数传递的方式实现的。

    Java是一种固执己见的语言,它具有很好的可读性,初级程序员很容易上手,具有长期稳定性和可支持性。但这些设计决定也付出了一定的代价:冗长的代码,类型系统与其它语言相比显得缺乏弹性。

    最近看python的一本书,里面讲到重构,记忆最深的一句话是: “保证代码能够正确地运行,但可做进一步的改进——将代码划分为一系列完成具体工作的函数。这样的过程被称为重构。重构让代码更清晰,更易于理解,更容易扩展”。

    其实 Java8——Lambda、流Stream、Collector、方法引用…..的一些函数方法,属于重构优化的一部分,方便大家扩展开发,写出更清晰的业务代码块。

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: 同时计算一个列表的和、最大值、最小值、平均值、元素个数、奇偶分组、指数、排序
 * @author taohanlin
 * @date 2018年7月3日 下午4:46:57
 */
public class FunctionUtil {

 public static <T, R> List<R> multiGetResult(List<Function<List<T>, R>> functions, List<T> list) {
	return functions.stream().map(f -> f.apply(list)).collect(Collectors.toList());
	}

 public static void main(String[] args) {
	System.out.println(multiGetResult(
		Arrays.asList(
			list -> list.stream().collect(Collectors.summarizingInt(x -> x)),
			list -> list.stream().filter(x -> x < 50).sorted()
			 .collect(Collectors.toList()),
			list -> list.stream().collect(Collectors
			 .groupingBy(x -> (x % 2 == 0 ? "even" : "odd"))),
			list -> list.stream().sorted().collect(Collectors.toList()),
			list -> list.stream().sorted().map(Math::sqrt)
			 .collect(Collectors.toMap(x -> x, y -> Math.pow(2, y)))),
		     Arrays.asList(64, 49, 25, 16, 9, 4, 1, 81, 36)));
	}
}

下面是Java8–List转为Map、分组、过滤、求和等操作

    先定义一个Apple对象:

public class Apple {

	private Integer id;
	private String name;
	private BigDecimal money;
	private Integer num;

  //省略get,set,构造方法....

    测试用例:

/**
 * @Description: TODO
 * @author taohanlin
 * @date 2018年7月3日 上午11:50:31
 */
public class Java8Util {

 public static void main(String[] args) {

	List<Apple> appleList = new ArrayList<>();
	Apple buleApple = new Apple(1, "蓝色苹果", new BigDecimal("20.50"), 10);
	Apple greenApple = new Apple(2, "绿色苹果", new BigDecimal("10.50"), 20);
	Apple redApple = new Apple(3, "红色苹果", new BigDecimal("80.50"), 30);
	Apple yellowApple = new Apple(1, "黄色苹果", new BigDecimal("180.50"), 50);

	appleList.add(buleApple);
	appleList.add(greenApple);
	appleList.add(redApple);
	appleList.add(yellowApple);

	/**
	 * List >- Map ⚠️:如果有重复的key,会报Duplicate key...
	 */

	Map<Integer, Apple> appleDuplicateMap = appleList.stream().collect(Collectors.toMap(Apple::getId, a -> a));
	System.out.println(JsonUtil.toJson(appleDuplicateMap));

	/**
	 * 因为buleApple与yellowApple的id都是1,所以上面转map会报错。 防止报Duplicate key...
	 * 可以用(k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
	 */
	Map<Integer, Apple> appleMap = appleList.stream().collect(Collectors.toMap(Apple::getId, a -> a, (k1, k2) -> k1));
	System.out.println(JsonUtil.toJson(appleMap));
	// {1:{"id":1,"money":20.50,"name":"蓝色苹果","num":10},2:{"id":2,"money":10.50,"name":"绿色苹果","num":20},3:{"id":3,"money":80.50,"name":"红色苹果","num":30}}

	/**
	 * 分组:List里面的对象元素,以某个属性来分组,例如,以id分组,将id相同的放在一起:
	 */
	Map<Integer, List<Apple>> groupApple = appleList.stream().collect(Collectors.groupingBy(Apple::getId));
	System.out.println(JsonUtil.toJson(groupApple));
	// {1:[{"id":1,"money":20.50,"name":"蓝色苹果","num":10},{"id":1,"money":180.50,"name":"黄色苹果","num":50}],2:[{"id":2,"money":10.50,"name":"绿色苹果","num":20}],3:[{"id":3,"money":80.50,"name":"红色苹果","num":30}]}

	// 只要某个字段的分组
	Map<Integer, List<Integer>> groupAppleByNum = appleList.stream()
		.collect(Collectors.groupingBy(Apple::getId, Collectors.mapping(Apple::getNum, Collectors.toList())));
	System.out.println(JsonUtil.toJson(groupAppleByNum));
	// {1:[10,50],2:[20],3:[30]}
	/**
	 * 过滤:从集合中过滤出来符合条件的元素:
	 */
	List<Apple> filterApple = appleList.stream().filter(a -> a.getName().equals("红色苹果")).collect(Collectors.toList());
	System.out.println(JsonUtil.toJson(filterApple));
	// [{"id":3,"money":80.50,"name":"红色苹果","num":30}]

	/**
	 * 求和:将集合中的数据按照某个属性求和:
	 */
	// BigDecimal
	BigDecimal totalMoney = appleList.stream().map(Apple::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
	System.out.println(totalMoney);// 292.00
	// Integer
	int sum = appleList.stream().mapToInt(Apple::getNum).sum();
	System.out.println(sum);// 110

	/**
	 * 求max,min值,排序。
	 */
	List<Integer> list = Lists.newArrayList(3, 5, 2, 9, 1);
	int maxInt = list.stream().max(Integer::compareTo).get();// 9
	int minInt = list.stream().min(Integer::compareTo).get();// 1
	int sumSize = Stream.of("Apple", "Banana", "Orange", "Pear").parallel().map(s -> s.length()).reduce(Integer::sum).get();
	System.out.println(sumSize);// 字符串长度为21
	List<Integer> sortedList = list.stream().sorted(Integer::compareTo).collect(Collectors.toList());
	System.out.println(JsonUtil.toJson(sortedList));// [1,2,3,5,9]
	//等效Collections.sort(list);,对象则可重写bean的compareTo方法实现排序											// 

	}

   

    未完待续……

百度已收录

桃园结义 , 版权所有丨如未注明 , 均为原创丨转载请注明Java8的部分特性 “函数式编程”

您必须 登录 才能发表评论!