背景介绍: 公司用的 jdk1.7版本,为了使用1.8版本中的Stream API ,精简代码量,用SpringEL表达式进行功能模拟
直接上工具类 SpringELStreamSimulater:
import java.math.BigDecimal; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.collections.comparators.ComparableComparator; import org.apache.commons.lang.StringUtils; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; /** * 通过 SpringEL 表达式,对 java8 Stream API 的模拟 * * <pre> * interface class * ----------------------------------------------- * ExpressionParser SpelExpressionParser * Expression SpelExpression * EvaluationContext StandardEvaluationContext * </pre> * */ public class SpringELStreamSimulater<V> { private EvaluationContext context = new StandardEvaluationContext(); private ExpressionParser parser = new SpelExpressionParser(); private Collection<V> dataList; private SpringELStreamSimulater() { } public static <V> SpringELStreamSimulater<V> of(Collection<V> list) { if (list == null) { throw new RuntimeException(); } SpringELStreamSimulater<V> stream = new SpringELStreamSimulater<V>(); stream.dataList = list; return stream; } /** * 绑定上下文,用法:#name * * @param value 绑定方法时,必须是Method类型 */ public SpringELStreamSimulater<V> bind(String name, Object value) { context.setVariable(name, value); return this; } /* * intermediate */ /** * 过滤 */ public SpringELStreamSimulater<V> filter(String relationalExpression) { Expression exp = parser.parseExpression(relationalExpression); List<V> filter = Lists.newLinkedList(); for (V each : dataList) { if (exp.getValue(context, each, Boolean.class)) { filter.add(each); } } dataList = filter; return this; } /** * 映射 */ public <K> SpringELStreamSimulater<K> map(String functinExpression, Class<K> desiredResultType) { Expression exp = parser.parseExpression(functinExpression); List<K> list = Lists.newLinkedList(); for (V each : dataList) { list.add(exp.getValue(context, each, desiredResultType)); } return SpringELStreamSimulater.of(list); } /** * 投影 */ public SpringELStreamSimulater<Object> projector(String propertyExpression) { return projector(propertyExpression, Object.class); } /** * 投影 */ public <K> SpringELStreamSimulater<K> projector(String propertyExpression, Class<K> desiredResultType) { Expression exp = parser.parseExpression(propertyExpression); List<K> list = Lists.newLinkedList(); for (V each : dataList) { list.add(exp.getValue(context, each, desiredResultType)); } return SpringELStreamSimulater.of(list); } /** * 去重,依据 Object.equals(Object) */ public SpringELStreamSimulater<V> distinct() { Set<V> filter = Sets.newHashSet(); for (V each : dataList) { filter.add(each); } dataList = filter; return this; } /** * 自然排序 */ @SuppressWarnings("unchecked") public SpringELStreamSimulater<V> sort() { return sort(ComparableComparator.getInstance()); } /** * 排序 */ public SpringELStreamSimulater<V> sort(Comparator<? super V> comparator) { if (!(dataList instanceof List)) { dataList = Lists.newArrayList(dataList); } Collections.sort((List<V>) dataList, comparator); return this; } /** * 截断 */ public SpringELStreamSimulater<V> limit(long maxSize) { if (maxSize < 0) { throw new IllegalArgumentException(); } if (dataList.size() > maxSize) { List<V> list = Lists.newLinkedList(); int num = 0; for (V each : dataList) { num++; if (num > maxSize) { break; } list.add(each); } dataList = list; } return this; } /* * terminal */ /** * 总计 */ public BigDecimal sum() { // 意味着dataList是纯数字组成的单一列表 return sum("#this"); } /** * 总计 */ public BigDecimal sum(String expressionString) { Expression exp = parser.parseExpression(expressionString); BigDecimal total = BigDecimal.ZERO; for (V each : dataList) { String val = exp.getValue(context, each, String.class); if (StringUtils.isBlank(val)) { continue; } total = total.add(new BigDecimal(val)); } return total; } /** * 平均 */ public BigDecimal avg(String expressionString, int scale) { return dataList.isEmpty() ? BigDecimal.ZERO : sum(expressionString).divide(new BigDecimal(dataList.size()), scale, BigDecimal.ROUND_HALF_UP); } /** * 总数 */ public long count() { return dataList.size(); } public List<V> toList() { if (dataList instanceof List) { return (List<V>) dataList; } return Lists.newArrayList(dataList); } public String toCSV() { return StringUtils.join(dataList, ","); } public Map<String, V> toMap(String expressionString) { return toMap(expressionString, String.class); } public <T> Map<T, V> toMap(String expressionString, Class<T> keyType) { Expression exp = parser.parseExpression(expressionString); Map<T, V> map = Maps.newHashMap(); for (V each : dataList) { map.put(exp.getValue(context, each, keyType), each); } return map; } public ListMultimap<String, V> toMultimap(String expressionString) { return toMultimap(expressionString, String.class); } public <T> ListMultimap<T, V> toMultimap(String expressionString, Class<T> keyType) { Expression exp = parser.parseExpression(expressionString); ListMultimap<T, V> multimap = ArrayListMultimap.create(); for (V each : dataList) { multimap.put(exp.getValue(context, each, keyType), each); } return multimap; } }应用举例:
1.过滤出list中所有属性id的值:
SpringELStreamSimulater.of(list).projector("id").toCSV();2.过滤出list中所有id以TAC开通的id
List<String> tacList =SpringELStreamSimulater.of(list).filter("id.startsWith('TAC')") .projector("id", String.class).toList();3.过滤出list中所有clazzId为某值的数组:
List<PublishTimetable> publishTimetableList =SpringELStreamSimulater.of(list).bind("clazzId", clazzId) .filter("clazzId == #clazzId").toList();4. 按照id进行排序
Collection<PublishTimetable> coll = ptMultimap.get(key); String ids = SpringELStreamSimulater.of(coll).projector("id").sort().toCSV();以上,欢迎指正交流