用过C#的人都知道lamda表达式作用于集合的power!简洁、易用、可读性强。比如从一个集合中取出所有符合某一条件的所有项:
var fields = skuField.GetFieldList();
<pre name="code" class="csharp">//取出属性集合中类型为单选类型且属性ID字符串含有“_20549_29148” 的所有属性项
var sizeFields = fields.FindAll(f => f.Type == FieldTypeEnum.SINGLECHECK && f.Id.Contains("_20549_29148"));
现在如何在java 低版本中如何实现类似功能?
可能是这样:
<span style="white-space:pre"> </span>List<Field> fields = skuField.getFieldList();
List<Field> sizeFields = new ArrayList<Field>();
for (Field f : fields) {
if (f.getType() == FieldTypeEnum.SINGLECHECK && f.getId().contains("_20549_29148")) {// 欧码
sizeFields.add(f);
}
}
如果不想总这么写循环,有没有更“优雅”点的方式呢?类C#中的Lamda表达式。
一、从集合中取出符合条件的项:
1、我们可以创建条件接口IMatch,如下
/**
* @author zhaojiwei YGCollectionInterface 2015年4月16日
* @param <T>
*/
public interface IMatch<T> {
boolean match(T t);
}
再创建一个集合帮助类YGCollectionHelper,专门实现一些方法,比如find,findAll等
/**
* @author zhaojiwei YGCollectionHelper 2015年4月16日
*/
public class YGCollectionHelper {
public static <T> T find(Collection<T> list, IMatch<T> collectionInterface) {
if (CollectionUtils.isEmpty(list)) { return null; }
for (T t : list) {
if (collectionInterface.match(t)) { return t; }
}
return null;
}
public static <T> List<T> findAll(Collection<T> list, IMatch<T> collectionInterface) {
if (CollectionUtils.isEmpty(list)) { return null; }
List<T> ts = new ArrayList<T>();
for (T t : list) {
if (t != null && collectionInterface.match(t)) {
ts.add(t);
}
}
return ts;
}
}
我们该如何使用该集合辅助类呢?很简单,如下代码:@Test
public void testYGCollection() {
List<Brand> brands = commodityBaseApiService.getAllBrands();
Brand brand = YGCollectionHelper.find(brands, new IMatch<Brand>() {
@Override
public boolean match(Brand b) {
return b.getBrandName().equals("耐克"); //boolean表达式:选出品牌名称为耐克的品牌项
}
});
if (brand != null) {
System.out.println(brand.getBrandDesc());
}
List<Brand> list1 = YGCollectionHelper.findAll(brands, new IMatch<Brand>() {
@Override
public boolean match(Brand t) {
return t.getDelFlag().equals(1); //选出集合中未删除的项
}
});
if (list1 != null) {
System.out.println(list1.size());
}
List<String> brandNames = YGCollectionHelper.select(brands, new ISingleMapping<Brand, String>() {
@Override
public String func(Brand t) {
if (t == null || StringUtils.isBlank(t.getBrandName())) { return null; }
return t.getBrandName();
}
});
if (CollectionUtils.isNotEmpty(brandNames)) {
for (String brandName : brandNames) {
System.out.println(brandName);
}
}
}
二、将一个集合中的元素映射为另一个元素集合(功能类似C# select、selectMany方法)
/**
* @author zhaojiwei
* IYGCollectionMapping
* 2015年4月16日
*/
public interface ISingleMapping<T,E> {
E func(T t);
}
多元素同时映射:
/**
* @author zhaojiwei IManyMapping 2015年4月16日
*/
public interface IManyMapping<T, E> {
Collection<E> selectMany(T t);
}
public static <T, E> List<E> select(Collection<T> list, ISingleMapping<T, E> singleMappingInterface) {
if (CollectionUtils.isEmpty(list)) { return null; }
List<E> result = new ArrayList<E>();
for (T t : list) {
E e = singleMappingInterface.func(t);
if (e != null) {
result.add(e);
}
}
return result;
}
public static <T, E> List<E> selectMany(Collection<T> list, IManyMapping<T, E> manyMapping) {
if (CollectionUtils.isEmpty(list)) { return null; }
List<E> result = new ArrayList<E>();
Collection<E> e = null;
for (T t : list) {
e = manyMapping.selectMany(t);
if (e != null) {
result.addAll(e);
}
}
return result;
}
如何使用?
List<String> brandNames = YGCollectionHelper.select(brands, new ISingleMapping<Brand, String>() {
@Override
public String func(Brand t) {
if (t == null || StringUtils.isBlank(t.getBrandName())) { return null; }
return t.getBrandName();
}
});
if (CollectionUtils.isNotEmpty(brandNames)) {
for (String brandName : brandNames) {
System.out.println(brandName);
}
}
三、其它功能点的实现
/**
* @Date:2015年4月16日
* @Author: zhaojiwei
* @Description:
*/
package com.yougou.gms.utils.ygcollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.alibaba.dubbo.common.utils.CollectionUtils;
/**
* @author zhaojiwei YGCollectionHelper 2015年4月16日
*/
public class YGCollectionHelper {
public static <T> T first(Collection<T> list) {
if (CollectionUtils.isEmpty(list)) return null;
int i = 0;
for (T t : list) {
if (i++ == 0) { return t; }
}
return null;
}
public static <T> boolean exists(Collection<T> list, IMatch<T> collectionInterface) {
if (CollectionUtils.isEmpty(list)) { return false; }
for (T t : list) {
if (collectionInterface.match(t)) { return true; }
}
return false;
}
public static <T> boolean all(Collection<T> list, IMatch<T> collectionInterface) {
if (CollectionUtils.isEmpty(list)) { return false; }
for (T t : list) {
if (!collectionInterface.match(t)) { return false; }
}
return true;
}
public static <T> boolean any(Collection<T> list, IMatch<T> collectionInterface) {
return exists(list, collectionInterface);
}
public static <T> T find(Collection<T> list, IMatch<T> collectionInterface) {
if (CollectionUtils.isEmpty(list)) { return null; }
for (T t : list) {
if (collectionInterface.match(t)) { return t; }
}
return null;
}
public static <T> List<T> findAll(Collection<T> list, IMatch<T> collectionInterface) {
if (CollectionUtils.isEmpty(list)) { return null; }
List<T> ts = new ArrayList<T>();
for (T t : list) {
if (t != null && collectionInterface.match(t)) {
ts.add(t);
}
}
return ts;
}
public static <T, E> List<E> select(Collection<T> list, ISingleMapping<T, E> singleMappingInterface) {
if (CollectionUtils.isEmpty(list)) { return null; }
List<E> result = new ArrayList<E>();
for (T t : list) {
E e = singleMappingInterface.func(t);
if (e != null) {
result.add(e);
}
}
return result;
}
public static <T, E> List<E> selectMany(Collection<T> list, IManyMapping<T, E> manyMapping) {
if (CollectionUtils.isEmpty(list)) { return null; }
List<E> result = new ArrayList<E>();
Collection<E> e = null;
for (T t : list) {
e = manyMapping.selectMany(t);
if (e != null) {
result.addAll(e);
}
}
return result;
}
}
在使用方法辅助类时,获取集合或作集合映射时,我们的重点或者说关注点集中在 条件表达式上,不用在反复滴写foreach循环遍历了。