Java将List集合的某一个对象的属性或枚举对应的值转换为数组解决方案

Java中List集合和枚举转换为数组解决方案

最近在做项目的时候,经常遇到将将一个List集合中的对象的某个属性字段取出,然后组装成该字段属性对应类型的数组,也遇到了将一个枚举中每个元素对应的值取出,组装成该枚举元素的值对应的数据类型的数组。因此特此来总结一下JDK8之前和JDK8 Stream API分别是怎么做到的。

需求:

下面Junit测试方法中具体的需求都有,不再赘述。

使用到的VO:

package SysBankpaycenterPo;

import java.io.Serializable;
import java.util.Date;

import org.springframework.format.annotation.DateTimeFormat;

/**
 * 银行支付结算渠道
 * 
 * @author hongwei.lian 
 * @date 2018年5月26日 下午6:16:36
 */
public class SysBankpaycenter implements Serializable {
	
	private static final long serialVersionUID = 1540054122375184486L;

	/**
	 * 支付渠道id
	 */
	private Integer paycenterId;
	
	/**
	 * 支付渠道名称
	 */
	private String payCenterName;
	
	/**
	 * 创建时间
	 */
	@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")  
	private Date createTime;
	
	/**
	 * 渠道类型  1=支付渠道 2=结算渠道
	 */
	private Integer payChannelType;

	/**
	 * 银行id sys_bank.id
	 */
	private Integer bankId;
	
	/**
	 * 银行账号(加密)
	 */
	private String accountName;
	
	/**
	 * 银行账户名称(加密)
	 */
	private String accountNumber;
	
	/**
	 * 省份
	 */
	private String province;
	
	/**
	 * 城市
	 */
	private String city;
	
	/**
	 * 银行账户所在分支行名称
	 */
	private String subBankName;
	
	/**
	 * 更新时间
	 */
	@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")  
	private Date updateTime;
	
	/**
	 * 默认渠道 
	 * 默认结算银行渠道规则说明:
	 * 1、没有指定结算渠道的项目的资金默认归集到此渠道;
	 * 2、各项目的费用归集到此默认渠道
	 */
	private Integer defaultChannel;
	
	/**
	 * 交易所id exchange.id
	 */
	private Integer exchangeId;
	
	/**
	 * 联行号
	 */
	private String subBankNo;
	
	/**
	 * 账户类型 
	 * 1、个人账户 
	 * 2、企业账户 
	 * 3、支付账户
	 */
	private Integer accountType;
	
	/**
	 * 是否启用 
	 * 1、启用 
	 * 0、停用
	 */
	private Integer useEnabled;
	
	/**
	 * 渠道父类id(新增20160525)
	 */
	private Integer payChannelCategoryId;
	
	/**
	 * 渠道父类名
	 */
	private String payChannelCategoryName;
	
	/**
	 * 渠道使用类型 
	 * 1、机构用户 
	 * 2、个人用户 
	 * 3、通用
	 */
	private Integer payChannelUserType;
	
	/**
	 * 渠道结算机构号
	 */
	private String payChannelAgencyNo;
	
	/**
	 * 发送绑卡短信验证码开关 
	 * 0、关,
	 * 1、开
	 */
	private Integer bindCardSmsSwitch;
	
	/**
	 * 招行支行地区号
	 */
	private String subBankAreaCode;

	public SysBankpaycenter(Integer paycenterId, String payCenterName) {
		this.paycenterId = paycenterId;
		this.payCenterName = payCenterName;
	}

	public Integer getBindCardSmsSwitch() {
		return bindCardSmsSwitch;
	}
	
	public void setBindCardSmsSwitch(Integer bindCardSmsSwitch) {
		this.bindCardSmsSwitch = bindCardSmsSwitch;
	}
	
	public void setPaycenterId(Integer value) {
		this.paycenterId = value;
	}
	
	public Integer getPaycenterId() {
		return this.paycenterId;
	}
	
	public void setPayCenterName(String value) {
		this.payCenterName = value;
	}
	
	public String getPayCenterName() {
		return this.payCenterName;
	}
	
	public void setCreateTime(java.util.Date value) {
		this.createTime = value;
	}
	
	public java.util.Date getCreateTime() {
		return this.createTime;
	}
	
	public void setPayChannelType(Integer value) {
		this.payChannelType = value;
	}
	
	public Integer getPayChannelType() {
		return this.payChannelType;
	}
	
	public void setBankId(Integer value) {
		this.bankId = value;
	}
	
	public Integer getBankId() {
		return this.bankId;
	}
	
	public void setAccountName(String value) {
		this.accountName = value;
	}
	
	public String getAccountName() {
		return this.accountName;
	}
	
	public void setAccountNumber(String value) {
		this.accountNumber = value;
	}
	
	public String getAccountNumber() {
		return this.accountNumber;
	}
	
	public void setProvince(String value) {
		this.province = value;
	}
	
	public String getProvince() {
		return this.province;
	}
	
	public void setCity(String value) {
		this.city = value;
	}
	
	public String getCity() {
		return this.city;
	}
	
	public void setSubBankName(String value) {
		this.subBankName = value;
	}
	
	public String getSubBankName() {
		return this.subBankName;
	}
	
	public void setUpdateTime(java.util.Date value) {
		this.updateTime = value;
	}
	
	public java.util.Date getUpdateTime() {
		return this.updateTime;
	}
	
	public void setDefaultChannel(Integer value) {
		this.defaultChannel = value;
	}
	
	public Integer getDefaultChannel() {
		return this.defaultChannel;
	}
	
	public void setSubBankNo(String value) {
		this.subBankNo = value;
	}
	
	public String getSubBankNo() {
		return this.subBankNo;
	}
	
	public void setAccountType(Integer value) {
		this.accountType = value;
	}
	
	public Integer getAccountType() {
		return this.accountType;
	}
	
	public void setUseEnabled(Integer value) {
		this.useEnabled = value;
	}
	
	public Integer getUseEnabled() {
		return this.useEnabled;
	}
	
	public void setPayChannelCategoryId(Integer value) {
		this.payChannelCategoryId = value;
	}
	
	public Integer getPayChannelCategoryId() {
		return this.payChannelCategoryId;
	}
	
	public void setPayChannelCategoryName(String value) {
		this.payChannelCategoryName = value;
	}
	
	public String getPayChannelCategoryName() {
		return this.payChannelCategoryName;
	}
	
	public void setPayChannelUserType(Integer value) {
		this.payChannelUserType = value;
	}
	
	public Integer getPayChannelUserType() {
		return this.payChannelUserType;
	}
	
	public void setPayChannelAgencyNo(String value) {
		this.payChannelAgencyNo = value;
	}
	
	public String getPayChannelAgencyNo() {
		return this.payChannelAgencyNo;
	}
	
	public Integer getExchangeId() {
		return exchangeId;
	}
	
	public void setExchangeId(Integer exchangeId) {
		this.exchangeId = exchangeId;
	}
	
	public String getSubBankAreaCode() {
		return subBankAreaCode;
	}
	
	public void setSubBankAreaCode(String subBankAreaCode) {
		this.subBankAreaCode = subBankAreaCode;
	}

}

使用到的枚举:

package com.qdfae.jdk.enums;

/**
 * 费用支付方式
 * 
 * @author hongwei.lian 
 * @date 2018年5月27日 下午8:07:49
 */
public enum FeePayTypeEnum {
	
	线上(1),
	线下(2);
	
	private int value;
	
	private FeePayTypeEnum(int value) {
		this.value = value;
	}

	public int getValue() {
		return value;
	}

	public void setValue(int value) {
		this.value = value;
	}
	
}

方案:

package com.qdfae.jdk.array;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.qdfae.jdk.enums.FeePayTypeEnum;

import SysBankpaycenterPo.SysBankpaycenter;
import cn.hutool.core.util.ArrayUtil;

/**
 * Java对象转换为数组测试类
 * 
 * @author hongwei.lian 
 * @date 2018年5月26日 下午6:20:34
 */
public class ObjectToArrayTest {
	
	/**
	 * 存储银行支付结算渠道的List集合
	 */
	private List<SysBankpaycenter> clearCenterList;
	
	/**
	 * 存储银行支付结算渠道Id的Integer数组
	 */
	private Integer[] paycenterIdIntegerArray;
	
	/**
	 * 存储银行支付结算渠道Id的int数组
	 */
	private int[] paycenterIdIntArray;
	
	/**
	 * 存储支付类型对应枚举的数值的Integer数组
	 */
	private Integer[] payTypeIntegerArray;
	
	/**
	 * 存储支付类型对应枚举的数值的int数组
	 */
	private int[] payTypeIntArray;
	
	/**
	 * 初始化
	 * 
	 * 使用到的API
	 * List<E>接口
	 * int size();
	 * 
	 * 凡是继承java.lang.Enum类的自定义枚举在javac
	 * 编译时候都会加上一个public static的
	 * values()方法,方便我们使用
	 * 
	 * 数组的length属性字段是在JVM运行自动
	 * 为数组类java.lang.reflect.Array类提供的length
	 * 字段,可以使用native方法getLength()获取到
	 * 
	 *  
	 * @author hongwei.lian  
	 * @date 2018年5月26日 下午6:29:59
	 */
	@Before
	public void init() {
		//-- 初始化列表
		clearCenterList = new ArrayList<>();
		clearCenterList.add(new SysBankpaycenter(1001, "青岛农商行"));
		clearCenterList.add(new SysBankpaycenter(1002, "中金支付"));
		clearCenterList.add(new SysBankpaycenter(1003, "招商银行"));
		clearCenterList.add(new SysBankpaycenter(1004, "光大银行"));
		clearCenterList.add(new SysBankpaycenter(1005, "民生银行"));
		clearCenterList.add(new SysBankpaycenter(1006, "中金结算"));
		clearCenterList.add(new SysBankpaycenter(1007, "平安银行"));
		clearCenterList.add(new SysBankpaycenter(1008, "青岛清算中心"));
		//-- 创建数组
		paycenterIdIntegerArray = new Integer[clearCenterList.size()];
		paycenterIdIntArray = new int[clearCenterList.size()];
		payTypeIntegerArray = new Integer[FeePayTypeEnum.values().length];
		payTypeIntArray = new int[FeePayTypeEnum.values().length];
	}
	
	/**
	 * 遍历方式一
	 * JDK8之前的foreach形式
	 * 
	 * ArrayUtil来自开源出来的hutool工具包
	 * 主页:http://www.hutool.cn/
	 * GItHub地址:https://github.com/looly/hutool/
	 * 
	 * ArrayUtil工具类
	 * public static <T> boolean isNotEmpty(final T... array) {
	 *     return (array != null && array.length != 0);
	 * }
	 * 
	 * public static boolean isNotEmpty(final int... array) {
	 *    return (array != null && array.length != 0);
	 * }
	 *  
	 * @author hongwei.lian  
	 * @date 2018年5月26日 下午6:57:36
	 */
	@After
	public void foreach1() {
		System.out.println("=========JDK8之钱遍历数组==========");
		if (ArrayUtil.isNotEmpty(paycenterIdIntegerArray)) {
			for (Integer clearCenter : paycenterIdIntegerArray) {
				if (Objects.nonNull(clearCenter)) {
					System.out.println(clearCenter);
				}
			}
		}
		if (ArrayUtil.isNotEmpty(paycenterIdIntArray)) {
			for (int clearCenter : paycenterIdIntArray) {
				if (clearCenter != 0) {
					System.out.println(clearCenter);
				}
			}
		}
		if (ArrayUtil.isNotEmpty(payTypeIntegerArray)) {
			for (Integer payType : payTypeIntegerArray) {
				if (Objects.nonNull(payType)) {
					System.out.println(payType);
				}
			}
		}
		if (ArrayUtil.isNotEmpty(payTypeIntArray)) {
			for (int payType : payTypeIntArray) {
				if (payType != 0) {
					System.out.println(payType);
				}
			}
		}
	}
	
	/**
	 * 遍历方式二
	 * JDK8 Stream API
	 * 
	 * 使用的API
	 * JDK2 提供的Arrays工具类
	 * public static <T> Stream<T> stream(T[] array) {
	 *    return stream(array, 0, array.length);
	 * }   
	 * 
	 * public static IntStream stream(int[] array) {
     *    return stream(array, 0, array.length);
     * }
     * 
     * JDK8提供的Stream<T>接口和Consumer<T>接口
     * public interface Stream<T> extends BaseStream<T, Stream<T>> {
     *     void forEach(Consumer<? super T> action);
     * }
     * 
     * JDK8提供的IntStream接口和IntConsumer接口
     * public interface IntStream extends BaseStream<Integer, IntStream>  {
     *     void forEach(IntConsumer action);
     * }
	 *  
	 * @author hongwei.lian  
	 * @date 2018年5月26日 下午6:58:28
	 */
	@After
	public void foreach2() {
		System.out.println("=========JDK8 Stream API遍历数组==========");
		if (ArrayUtil.isNotEmpty(paycenterIdIntegerArray)) {
			Arrays.stream(paycenterIdIntegerArray)
			           .filter(Objects::nonNull)
			           .forEach(System.out::println);
		}
		if (ArrayUtil.isNotEmpty(paycenterIdIntArray)) {
			Arrays.stream(paycenterIdIntArray)
			           .filter(paycenterId -> paycenterId != 0)
			           .forEach(System.out::println);
		}
		if (ArrayUtil.isNotEmpty(payTypeIntegerArray)) {
			Arrays.stream(payTypeIntegerArray)
			           .filter(Objects::nonNull)
			           .forEach(System.out::println);
		}
		if (ArrayUtil.isNotEmpty(payTypeIntArray)) {
			Arrays.stream(payTypeIntArray)
		 	           .filter(paycenterId -> paycenterId != 0)
	                   .forEach(System.out::println);
		}
	}
	
	/**
	 * 方法一:普通方式
	 * 
	 * List集合转换为数组
	 * 需求:将List集合中存储的对象的paycenterId字段
	 *           取出组装称为这个字段对应数据类型的数组
	 * 数据源:
	 *              List<SysBankpaycenter>
	 * 目标源:          
	 *              Integer[] paycenterIdIntegerArray
	 *              int[] paycenterIdIntArray
	 *  
	 * @author hongwei.lian  
	 * @date 2018年5月26日 下午6:30:16
	 */
	@Test
	public void testListToArray1() {
		for (int i = 0; i < clearCenterList.size(); i++) {
			paycenterIdIntegerArray[i] = clearCenterList.get(i).getPaycenterId();
			paycenterIdIntArray[i] = clearCenterList.get(i).getPaycenterId();
		}
	}
	
	/**
	 * 方法二:JDK8 Stream API
	 * 
	 * List集合转换为数组
	 * 需求:将List集合中存储的对象的paycenterId字段
	 *           取出组装称为这个字段对应数据类型的数组
	 * 数据源:
	 *              List<SysBankpaycenter>
	 * 目标源:          
	 *              Integer[] paycenterIdArray
	 *  
	 * 使用的API
	 * JDK2提供的Collection<E>接口
	 * default Stream<E> stream() {
	 *     return StreamSupport.stream(spliterator(), false);
	 * }
	 * 
	 * JDK8提供的Stream<T>接口、Function<T, R>接口和IntFunction<R>接口
	 * <R> Stream<R> map(Function<? super T, ? extends R> mapper);
	 * <A> A[] toArray(IntFunction<A[]> generator);
	 * 
	 * @author hongwei.lian  
	 * @date 2018年5月26日 下午6:30:16
	 */
	@Test
	public void testListToArray2() {
		paycenterIdIntegerArray = clearCenterList.stream()
				                                                             .map(SysBankpaycenter::getPaycenterId)
				                                                             .toArray(Integer[]::new);
	}
	
	/**
	 * 方法三:JDK8 Stream API
	 * 
	 * List集合转换为数组
	 * 需求:将List集合中存储的对象的paycenterId字段
	 *           取出组装称为这个字段对应数据类型的数组
	 * 数据源:
	 *              List<SysBankpaycenter>
	 * 目标源:          
	 *              int[] paycenterIdArray
	 *  
	 *  使用的API
	 * JDK2提供的Collection<E>接口
	 * default Stream<E> stream() {
	 *     return StreamSupport.stream(spliterator(), false);
	 * }
	 * 
	 * JDK8提供的Stream<T>接口
	 * IntStream mapToInt(ToIntFunction<? super T> mapper);
	 * 
	 * ToIntFunction<T>接口
	 * int applyAsInt(T value);
	 * 
	 * IntStream接口
	 * int[] toArray();
	 *  
	 * @author hongwei.lian  
	 * @date 2018年5月26日 下午8:14:11
	 */
	@Test
	public void testListToArray3() {
		paycenterIdIntArray = clearCenterList.stream()
				                                                     .mapToInt(SysBankpaycenter::getPaycenterId)
				                                                     .toArray();
	}
	
	/**
	 * 方法一:JDK8之前普通方法
	 * 
	 * 枚举转换为数组
	 * 需求:将枚举中每个元素对应的数值,
	 *           取出组装称为这个字段对应数据类型的数组
	 * 数据源:
	 *              FeePayTypeEnum
	 * 目标源:          
	 *              Integer[] payTypeIntegerArray
	 *              int[] payTypeIntArray
	 *  
	 * @author hongwei.lian  
	 * @date 2018年5月27日 下午6:13:11
	 */
	@Test
	public void testEnumToArray1() {
		FeePayTypeEnum[] payTypeEnums = FeePayTypeEnum.values();
		for (int i = 0; i < payTypeEnums.length; i++) {
			payTypeIntegerArray[i] = payTypeEnums[i].getValue();
			payTypeIntArray[i] = payTypeEnums[i].getValue();
		}
	}
	
	/**
	 * 方法二:JDK8 Stream API
	 * 
	 * 枚举转换为数组
	 * 需求:将枚举中每个元素对应的数值,
	 *           取出组装称为这个字段对应数据类型的数组
	 * 数据源:
	 *              FeePayTypeEnum
	 * 目标源:          
	 *              Integer[] payTypeIntegerArray
	 *  
	 * @author hongwei.lian  
	 * @date 2018年5月27日 下午6:23:05
	 */
	@Test
	public void testEnumToArray2() {
		payTypeIntegerArray = Arrays.stream(FeePayTypeEnum.values())
				                                          .map(FeePayTypeEnum::getValue)
				                                          .toArray(Integer[]::new);
	}
	
	/**
	 * 方法三:JDK8 Stream API
	 * 
	 * 枚举转换为数组
	 * 需求:将枚举中每个元素对应的数值,
	 *           取出组装称为这个字段对应数据类型的数组
	 * 数据源:
	 *              FeePayTypeEnum
	 * 目标源:          
	 *              int[] payTypeIntArray
	 *  
	 * @author hongwei.lian  
	 * @date 2018年5月27日 下午6:23:09
	 */
	@Test
	public void testEnumToArray3() {
		payTypeIntArray = Arrays.stream(FeePayTypeEnum.values())
				                                   .mapToInt(FeePayTypeEnum::getValue)
				                                   .toArray();
	}

}

差不多使用JDK8快一年了,每次写代码总会想着去用JDK8 Stream API实现一遍,根本停不下来。通过看一些JDK源码,发现JDK8增加的东西好多都是值得我们学习使用的,无论是思想上和代码逻辑上都是一种新的编程方式在Java这种语言的体现,与时俱进。



猜你喜欢

转载自blog.csdn.net/erlian1992/article/details/80471988