lambdaj (集合操作)
http://www.cnblogs.com/jcli/archive/2013/01/09/2851906.html
lambdJ提供了一个DSL的语法去对集合进行相关操作。DSL 就是 Domain specific Language,精髓在「Domain」一词,「领域业务专门语言」,就是特定一个业务领域所专有的语言形式。比如我们所熟悉的SQL语言,就是一门DSL语言,它是专门针对数据库操作的语言。那lambdJ就是一个专门针对「集合」操作的DSL语言。
lambdJ提供了一个DSL的语法去对集合进行相关操作。DSL 就是 Domain specific Language,精髓在「Domain」一词,「领域业务专门语言」,就是特定一个业务领域所专有的语言形式。比如我们所熟悉的SQL语言,就是一门DSL语言,它是专门针对数据库操作的语言。那lambdJ就是一个专门针对「集合」操作的DSL语言。
下面我们就要看下如果使用它:
我们先定义一个类,它将会被我们要操作的集合对象包含。
1 2 3 4 5 6 7 8 |
Java代码 public class Person implements Serializable{ private static final long serialVersionUID = -5626560607865508210L; private int id; private String name; private int age; } |
//初始化一个集体对象
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Java代码 List<Person> persons = new ArrayList<Person>(); Person p = new Person(); p.setId(1); p.setName("张三"); p.setAge(28); persons.add(p); p = new Person(); p.setId(2); p.setName("李四"); p.setAge(35); persons.add(p); |
1 2 3 |
joinFrom(连接字段) Java代码 String names = joinFrom(persons).getName();//output:张三, 李四 |
还可以自定义拼接符
1 2 |
Java代码 String names = joinFrom(persons,"--").getName();//output: 张三--李四 |
select(条件选择)
1 2 3 |
//筛选出年龄大于33岁的人 Java代码 List<Person> ageGreaterThan33 = select(persons,having(on(Person.class).getAge(),Matchers.greaterThan(33))); |
selectMax,selectMin(最大/最小 对象)
1 2 |
Java代码 Person personWithMaxAge = selectMax(persons, on(Person.class).getAge());//得到年龄最大的人 |
max,min(最大/最小 对象属性值)
1 2 |
Java代码 int maxAge = max(persons, on(Person.class).getAge());//获得集合中年龄最大的那个值 |
maxFrom,minFrom(和max,min功能一样)
1 2 |
Java代码 int maxAge = maxFrom(persons).getAge();//获得集合中年龄最大的那个值,和上面的max一样功能,形式不同而也 |
sum,sunFrom(求和)
1 2 3 |
Java代码 int ageSum = sumFrom(persons).getAge(); int ageSum = sum(persons, on(Person.class).getAge()); |
sort(排序)
1 2 |
Java代码 List<Person> sortByAge = sort(persons, on(Person.class).getAge()); |
extract(抽取字段属性组成集合)
1 2 |
Java代码 List<Integer> ageList = extract(persons, on(Person.class).getAge()); |
index(以某字字段属性为关键值分组)
1 2 |
Java代码 Map<String,Person> mapByName = index(persons, on(Person.class).getName()); |
我这里写的都是很简单的例子,详细的功能介绍请查看官网上的ppt。总之只有你想不到,没有它做不到的集合操作功能。
还有,如果大家在工作中遇到很变态的集合操作而不知道怎么写时(就像很复杂的sql写法时),可以在这里留言我们一起讨论学习下。
一个例子:
http://outofmemory.cn/code-snippet/2961/lambdaj-skeleton-usage-example
测试用Bean类:产品
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
Java代码 package cn.outofmemory; /** * 测试用bean对象,产品 * @author 乔学士 * */ public class Product { private int id; private String name; private double price; private double weight; private String type; public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } public String getType() { return type; } public void setType(String type) { this.type = type; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString() { return "Product [id=" + id + ", name=" + name + ", price=" + price + ", type=" + type + ", weight=" + weight + "]"; } } |
生产产品的工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
Java代码 package info.yiwen.data; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * 生产产品的工厂 * @author 乔学士 * */ public class ProductFactory { public static List<Product> genRandomProduct(int amount){ if(amount < 0 ){ amount = 1; } Random random = new Random(); List<Product> ps = new ArrayList<Product>(amount); for(int i = 0; i < amount; i++){ Product p = new Product(); int randomNum = random.nextInt(100); p.setId(i+1); p.setId(i+1); p.setName("name" + randomNum); p.setPrice(Math.round(random.nextDouble() * 1000)); p.setWeight(Math.round(random.nextDouble() * 1000)); p.setType("type" + randomNum); ps.add(p); } return ps; } } |
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
Java代码 package info.yiwen.test; import java.util.Iterator; import java.util.List; import java.util.Map; import ch.lambdaj.function.closure.Closure; import info.yiwen.data.Product; import info.yiwen.data.ProductFactory; import static ch.lambdaj.Lambda.*; import static ch.lambdaj.collection.LambdaCollections.*; import static org.hamcrest.Matchers.*; /** * 测试类,方便起见,没有用jUnit * @author 乔学士 * */ public class Test { public static void main(String[] args) { List<Product> ps = ProductFactory.genRandomProduct(10); printl(1); //1.简单例子 //对每个product都设置price为100 //forEach(ps).setPrice(100); //对每个product都设置setPrice为100 //按重量从小到大进行排序 ps = sort(ps, on(Product.class).getWeight()); print(ps); printl(2); //2.joinFrom 连接某个属性,中间默认用逗号加空格(", "), 可以自定义分隔符 //连接每个product对象的name String names = joinFrom(ps).getName(); //连接每个product对象的name,间隔符为 ":" String names2 = joinFrom(ps,":").getName(); System.out.println(names); System.out.println(names2); printl(3); //3.select //从ps中选择出重量大于等于500的 List<Product> ps2 = select(ps, //注意下面greaterThanOrEqualTo方法中参数的类型一定要和getWeight严格相等 having(on(Product.class).getWeight(), greaterThanOrEqualTo(new Double(500))) ); System.out.println(ps2); printl(4); //4.selectMin找到最小的, also selectMax //找到重量最轻的产品 Product p = selectMin(ps, on(Product.class).getWeight()); System.out.println(p); printl(5); //5.max and maxFrom, also min and minFrom //找到最重的产品的重量(两种方法) //5.1 double weight1 = max(ps, on(Product.class).getWeight()); //5.2 double weight2 = maxFrom(ps).getWeight(); System.out.println(weight1 + "," + weight2); printl(6); //6.extract,抽取所有对象的某一列返回值 //得到每个产品的id //6.1 使用on List<Integer> ids = extract(ps, on(Product.class).getId()); System.out.println(ids); //6.2 使用属性名 List<?> ids2 = extractProperty(ps, "id"); System.out.println(ids2); printl(7); //7.index 返回一个map,value是每个对象,key是对象的某个属性 //返回一个key为id,value是对象的Map Map<Integer, ?> map = index(ps, on(Product.class).getId()); print(map); printl(8); //8.with 使用更为流畅的方法 //找到重量大于400的产品的id列表,并排序 //8.1原始方法 List<Double> prices1 = sort( extract( select(ps, having(on(Product.class).getWeight(), greaterThan(400.0))), on(Product.class).getPrice() ), on(Double.class).doubleValue() ); //8.2使用with的方法 List<Double> prices2 = with(ps) .retain(having(on(Product.class).getWeight(), greaterThan(400.0))) .extract(on(Product.class).getPrice()) .sort(on(Double.class).doubleValue()); System.out.println(prices1); System.out.println(prices2); printl(9); //9.闭包 ,of(T t) 返回T类型 Closure println = closure(); //创建一个closure,放到ThreadLocal中 of(System.out).println(var(String.class)); //of方法从ThreadLocal中得到这个Closure println.apply("hello"); println.each("hello","oschina"); } static void print(Iterable<?> ps){ Iterator<?> it = ps.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } static void print(Map<?, ?> map){ for(Map.Entry<?, ?> e :map.entrySet()){ System.out.println(e.getKey() + ":" + e.getValue()); } } static void printl(int itemNo){ System.out.println("--------------------" + itemNo + "---------------------"); } } |