初始化程序
private static List<User> initData() {
User user1 = new User(1, 10, "1994-1-1", "15");
User user2 = new User(2, 20, "1995-1-1", "25");
User user3 = new User(3, 30, "1996-1-1", "25");
User user4 = new User(4, 40, "1997-1-1", "45");
List<User> userList = new ArrayList<>(4);
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
return userList;
}
1.某字段取Map<String, List<Object>>
/**
* 筛选出不同key的数据,如name=1,2,1,3,以name为key则筛选出:
* 1:User1,User3
* 2:User2
* 3:User4
* @param userList
*/
public static void test1(List<User> userList) {
/**
* Map的key与最后的get*()方法返回数据关联,注意基础类型需用包装类型接收
*/
Map<Integer, List<User>> idMap = userList.stream().collect(Collectors.groupingBy(User::getId));
System.out.println(idMap);
Map<String, List<User>> ageMap = userList.stream().collect(Collectors.groupingBy(User::getMoney));
System.out.println(ageMap);
}
输出结果
{
1=[User(id=1, age=10, birthday=1994-1-1, money=15)],
2=[User(id=2, age=20, birthday=1995-1-1, money=25)],
3=[User(id=3, age=30, birthday=1996-1-1, money=25)],
4=[User(id=4, age=40, birthday=1997-1-1, money=45)]
}
{
45=[User(id=4, age=40, birthday=1997-1-1, money=45)],
25=[
User(id=2, age=20, birthday=1995-1-1, money=25),
User(id=3, age=30, birthday=1996-1-1, money=25)],
15=[User(id=1, age=10, birthday=1994-1-1, money=15)]
}
2.某字段为key,另一字段为value
public static void test4(List<User> userList) {
Map<Integer, String> map = userList.stream().collect(Collectors.toMap(User::getAge, User::getBirthday));
System.out.println(map);
}
输出结果
{20=1995-1-1, 40=1997-1-1, 10=1994-1-1, 30=1996-1-1}
3.某字段求和(求总条数)
public static void test2(List<User> userList) {
/**
* 求和:这里如果get*数据类型对应支持:mapToDouble/mapToLong/mapToInt
*/
int avgAge = userList.stream().mapToInt(User::getAge).sum();
/**
* 求数据条数
*/
long count = userList.stream().mapToInt(User::getAge).count();
System.out.println(avgAge);
System.out.println(count);
}
结果信息
100
4
4.筛选某字段成List集合
public static void test3(List<User> userList) {
List<Integer> ageList = userList.stream().map(User::getAge).collect(Collectors.toList());
System.out.println(ageList);
}
输出结果
[10, 20, 30, 40]
这里也可看到一样可以转成Map,Set
5.筛选某字段成Array数组
public static void test2(List<User> userList) {
/**
* 转成数组,这里的数组类型也和get*挂钩
*/
int[] ageArray = userList.stream().mapToInt(User::getAge).toArray();
for (int i : ageArray) {
System.out.print(i + ",");
}
}
输出结果
10,20,30,40,
6.统计某个字段个数并排序
private JSONObject getTopN(List<User> userList) {
// 计算前6
Map<String, List<User>> countMap = userList.stream().collect(CollectionsUtil.groupingByWithNullKeys(User::getAge));
// 筛选topN
List<String> keyOfTopN = countMap.entrySet().stream()
// e1-e2降序,反之升序
.sorted((Map.Entry<String, List<User>> e2, Map.Entry<String, List<User>> e1) -> e1.getValue().size() - e2.getValue().size())
.map(entry -> entry.getKey()).collect(Collectors.toList());
JSONObject json = new JSONObject(6,true);
for (String key : keyOfTopN) {
if (StringUtils.isEmpty(key)) {
continue;
}
// 足直接返回
if (json.size() >= 6) {
break;
}
json.put(key, countMap.get(key).size());
}
return json;
}
其中,CollectionsUtil.groupingByWithNullKeys为重写Collections.groupBy方法,解决不允许null key的异常
public class CollectionsUtil {
/**
* 重写Collectors.groupingBy,允许null key
*/
public static <T, A> Collector<T, ?, Map<A, List<T>>> groupingByWithNullKeys(Function<? super T, ? extends A> classifier) {
return Collectors.toMap(classifier, Collections::singletonList,
(List<T> oldList, List<T> newEl) -> {
List<T> newList = new ArrayList<>(oldList.size() + 1);
newList.addAll(oldList);
newList.addAll(newEl);
return newList;
});
}
}
其中, JSONObject json = new JSONObject(6,true); 标识初始化大小为6,需要按存入顺序输出的JSONObject
源码:
// 不指定大小,初始化16
public JSONObject(boolean ordered) {
this(16, ordered);
}
// 指定大小用指定的,排序则LinkedHashMap,都这HashMap
public JSONObject(int initialCapacity, boolean ordered) {
if (ordered) {
this.map = new LinkedHashMap(initialCapacity);
} else {
this.map = new HashMap(initialCapacity);
}
}
即:不排序初始化HashMap,排序初始化LinkedHashMap,这也是为什么Map存储时候顺序乱,则更改为LinkedHashMap的原因,至于传入大小,也是为了避免CPU开销,尽量用多少初始化多少