List集合的排序,求和,取最大值,按照条件过滤

实例

public class Java8Test {
    public static void main(String[] args) {
        Person p1 = new Person("麻子", 31);
        Person p2 = new Person("李四", 20);
        Person p3 = new Person("王五", 26);
        List personList = new ArrayList();
        personList.add(p1);
        personList.add(p2);
        personList.add(p3);
    }
}

1、遍历

personList.forEach(p -> System.out.println(p.getAge()));

2、排序

(1)单属性排序

按照person的 age进行排序

方法一

personList.sort((o1, o2) -> o1.getAge().compareTo(o2.getAge())); //正序
personList.sort((o1, o2) -> o2.getAge().compareTo(o1.getAge())); //倒序

方法二

personList.sort(Comparator.comparing(Person::getAge)); // 正序
personList.sort(Comparator.comparing(Person::getAge).reversed()); // 倒序

(2)多属性排序

按照person的name倒序,然后按照age正序

方法一

Collections.sort(personList, Comparator.comparing(Person::getName, Comparator.reverseOrder()) // 按照姓名倒序
		.thenComparing(Person::getAge, Comparator.naturalOrder())); // 在前面的基础上,按照年龄正序

方法二

personList.stream().sorted(Comparator.comparing(Person::getName).thenComparing(Person::getAge)).collect(Collectors.toList());

3、提取某一列值

(1)提取

//从对象列表中提取一列(以age为例)
List<Integer> nameList = personList.stream().map(StudentInfo::getAge).collect(Collectors.toList());

(2)提取后重排【使用distinct()函数去重】

//从对象列表中提取一列(以age为例)
List<Integer> nameList = personList.stream().map(StudentInfo::getAge).distinct().collect(Collectors.toList());

4、统计

(1)最大

//获取年龄最大的Person

//方法一
Person maxAgePerson = personList.stream().max(Comparator.comparing(Person::getAge)).get();
System.out.println(maxAgePerson.getAge());
//方法二
int maxAge = personList.stream().mapToInt(Person::getAge).max().orElse(0);

(2)最小

//获取年龄最小的Person

Person minAgePerson = personList.stream().min(Comparator.comparing(Person::getAge)).get();
System.out.println(minAgePerson.getAge());

(3)过滤

//过滤出年龄是20的person,想过滤出什么条件的都可以

List personList1 = personList.stream().filter(person -> person.getAge() == 20).collect(Collectors.toList());

(4)统计

//统计出年龄等于20的个数

long count = personList.stream().filter(person -> person.getAge() == 20).count();

(5)平均

//获得年龄的平均值

double asDouble = personList.stream().mapToInt(person -> person.getAge()).average().getAsDouble();

(6)求和

//获得年龄的求和

int sum = personList.stream().mapToInt(person -> person.getAge()).sum();

5、转化

(1)List转Map

Stream将List转换为Map,使用Collectors.toMap方法进行转换
(1)指定key-value,value是对象中的某个属性值

Map<Integer,String> userMap1 = userList.stream().collect(Collectors.toMap(User::getId,User::getName));

(2)指定key-value,value是对象本身,User->User 是一个返回本身的lambda表达式

Map<Integer,User> userMap2 = userList.stream().collect(Collectors.toMap(User::getId,User->User));

(3)指定key-value,value是对象本身,Function.identity()是简洁写法,也是返回对象本身

Map<Integer,User> userMap3 = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));

(4)指定key-value,value是对象本身,Function.identity()是简洁写法,也是返回对象本身,key 冲突的解决办法,这里选择key2覆盖key1

Map<Integer,User> userMap4 = userList.stream().collect(Collectors.toMap(User::getId, Function.identity(),(key1,key2)->key2));

(2)Map转List

map.entrySet().stream().map(e -> new Person(e.getKey(),e.getValue())).collect(Collectors.toList());
map.keySet().stream().collect(Collectors.toList());
map.values().stream().collect(Collectors.toList());

(3)String转List

//(1)不需要处理
<String> list = Arrays.asList(str.split(","));
//(2)需要处理
List<String> list = Arrays.asList(str.split(",")).stream().map(string -> String.valueOf(string)).collect(Collectors.toList());

list.forEach(string -> System.out.println(string));

(4)List转String

//1:针对对象集合,例如将City中的城市名称以逗号拼接,转成字符串
List<City> list;
String str = list.stream().map(City::getCity).collect(Collectors.joining(","));
//2:针对字符串集合
List<String> list;
//方法1
String str = String.join(",", list);
//方法2
String str = list.stream().collect(Collectors.joining(","));

(5)List对象转换

@Data
public class CityDTO {
    private String city;
    private Integer total;
    private Integer num;

    public CityDTO(){}

    public CityDTO(CityDO doo){
        this.city =doo.getCity();
        this.total =doo.getTotal();
    }
}
List<CityDO> dos = Arrays.asList(new CityDO("上海",11),new CityDO("武汉",22));
List<CityDTO> dtos = dos.stream().map(CityDTO::new).collect(Collectors.toList());

6、分组

示例:

List<Score> scoreList = new ArrayList<>();         
scoreList.add(new Score().setStudentId("001").setScoreYear("2018").setScore(100.0));         
scoreList.add(new Score().setStudentId("001").setScoreYear("2019").setScore(59.5));         
scoreList.add(new Score().setStudentId("001").setScoreYear("2019").setScore(99.0));         
scoreList.add(new Score().setStudentId("002").setScoreYear("2018").setScore(99.6));

(1)根据某一个字段(scoreYear)进行分组

Map<String, List<Score>> map = scoreList.stream().collect(              
    Collectors.groupingBy(Score::getScoreYear)
);         
System.out.println(JSONUtil.toJsonPrettyStr(map));

(2)根据多个字段(scoreYear和studentId)进行分组

对于list多字段的分组操作,groupingBy内传入的是多个字段拼接起来的一个复合字段,分组后形成map的key,就是拼接后的复合字段

Map<String, List<Score>> map = scoreList.stream().collect(
    Collectors.groupingBy(
        score -> score.getScoreYear()+'-'+score.getStudentId()
    )
);        
System.out.println(JSONUtil.toJsonPrettyStr(map));

(3)分组后,提取某一字段的值作为value

Map<String, List<Double>> map = scoreList.stream().collect(
    Collectors.groupingBy(
        Collectors.groupingBy(Score::getScoreYear, Collectors.mapping(Score::getScore,Collectors.toList()))
    )
);        
System.out.println(JSONUtil.toJsonPrettyStr(map));

(4)如果分组属性存在null,先进行非空过滤

Map<String, List<Score>> map = scoreList.stream()
		.fillter(v -> StringUtils.isNotEmpty(v.getScoreYear()))
		.collect(
		    Collectors.groupingBy(
		        score -> score.getScoreYear()
		    )
);        
System.out.println(JSONUtil.toJsonPrettyStr(map));

(5)分组统计

//分组统计
Map<String, LongSummaryStatistics> collect = list.stream().collect(
                Collectors.groupingBy(Fruit::getType,
                        Collectors.summarizingLong(Fruit::getTotal)));
for (Map.Entry<String, LongSummaryStatistics> entry : collect.entrySet()) {
        LongSummaryStatistics longSummaryStatistics = entry.getValue();
        System.out.println("----------------key----------------" + entry.getKey());
        System.out.println("求和:" + longSummaryStatistics.getSum());
        System.out.println("求平均" + longSummaryStatistics.getAverage());
        System.out.println("求最大:" + longSummaryStatistics.getMax());
        System.out.println("求最小:" + longSummaryStatistics.getMin());
        System.out.println("求总数:" + longSummaryStatistics.getCount());
}

(6)以某个List集合元素为key分组

对List根据subActivityId中的元素进行分组,因为subActivityId是一个列表,而不是一个单独的值。

	List<ActivityRegistrationInfo> list = new ArrayList<>();
    ActivityRegistrationInfo v1 = new ActivityRegistrationInfo();
    v1.setActivityId(1L);
    v1.setSubActivityId(List.of(11L, 12L));
    v1.setNumOfPeople(10);
    list.add(v1);
    ActivityRegistrationInfo v2 = new ActivityRegistrationInfo();
    v2.setActivityId(1L);
    v2.setSubActivityId(List.of(13L, 12L));
    v2.setNumOfPeople(20);
    list.add(v2);

	//遍历所有的活动报名信息按照子活动分组
    Map<Long, List<ActivityRegistrationDTO>> groupedBySubActivityId = registerList.stream()
            .flatMap(ari -> ari.getSubActivityId().stream()
                    .map(id -> new AbstractMap.SimpleEntry<>(id, ari))) // 将每个subActivityId与对应的ActivityRegistrationInfo关联起来
            .collect(Collectors.groupingBy(
                    Map.Entry::getKey, // 分组的键是subActivityId
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList()) // 分组的值是ActivityRegistrationInfo的列表
            ));
                

7、List去重

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class ListUtil {

    public static List<String> list = Arrays.asList("1","2","2","3","3","4","4","5","6","7","8");
    public static List<City> cities = null;
    static {
        cities = new ArrayList<City>(){
            {
                add(new City("上海",11));
                add(new City("武汉",22));
                add(new City("武汉",55));
                add(new City("上海",33));
                add(new City("北京",33));
                add(new City("深圳",43));
            }
        };

    }
    public static void main(String[] args) {
        System.out.println(ListUtil.distinctElements(list));
        System.out.println(ListUtil.getNoDuplicateElements(list));
        System.out.println(ListUtil.getDuplicateElements(list));
        System.out.println(ListUtil.getDuplicateElementsForObject(cities));
        System.out.println(ListUtil.getNoDuplicateElementsForObject(cities));
        System.out.println(ListUtil.getElementsAfterDuplicate(cities));
        System.out.println(ListUtil.getDuplicateObject(cities));
        System.out.println(ListUtil.getNoDuplicateObject(cities));
        System.out.println(ListUtil.distinctObject(cities));
    }



    //去重后的集合 [1, 2, 3, 4, 5, 6, 7, 8]
    public static <T> List<T> distinctElements(List<T> list) {
        return list.stream().distinct().collect(Collectors.toList());
    }

    //lambda表达式 去除集合重复的值  [1, 5, 6, 7, 8]
    public static <T> List<T> getNoDuplicateElements(List<T> list) {
        // 获得元素出现频率的 Map,键为元素,值为元素出现的次数
        Map<T, Long> map = list.stream().collect(Collectors.groupingBy(p -> p,Collectors.counting()));
        System.out.println("getDuplicateElements2: "+map);
        return map.entrySet().stream() // Set<Entry>转换为Stream<Entry>
                .filter(entry -> entry.getValue() == 1) // 过滤出元素出现次数等于 1 的 entry
                .map(entry -> entry.getKey()) // 获得 entry 的键(重复元素)对应的 Stream
                .collect(Collectors.toList()); // 转化为 List
    }

    //lambda表达式 查找出重复的集合 [2, 3, 4]
    public static <T> List<T> getDuplicateElements(List<T> list) {
        return list.stream().collect(Collectors.collectingAndThen(Collectors
                            .groupingBy(p -> p, Collectors.counting()), map->{
                                map.values().removeIf(size -> size ==1); // >1 查找不重复的集合;== 1 查找重复的集合
                                List<T> tempList = new ArrayList<>(map.keySet());
                                return tempList;
                            }));
    }

    //利用set集合
    public static <T> Set<T> getDuplicateElements2(List<T> list) {
        Set<T> set = new HashSet<>();
        Set<T> exist = new HashSet<>();
        for (T s : list) {
            if (set.contains(s)) {
                exist.add(s);
            } else {
                set.add(s);
            }
        }
        return exist;
    }

    /**-----------对象List做处理--------------*/

    //查找对象中某个原属重复的  属性集合   [上海, 武汉]
    public static List<String> getDuplicateElementsForObject(List<City> list) {
        return list.stream().collect(Collectors.groupingBy(p -> p.getCity(),Collectors.counting())).entrySet().stream()
                .filter(entry -> entry.getValue() > 1) // >1 查找重复的集合;== 查找不重复的集合
                .map(entry -> entry.getKey())
                .collect(Collectors.toList());
    }

    //查找对象中某个原属未重复的  属性集合   [深圳, 北京]
    public static List<String> getNoDuplicateElementsForObject(List<City> list){
        Map<String,List<City>> map = list.stream().collect(Collectors.groupingBy(City::getCity));
        return map.entrySet().stream().filter(entry -> entry.getValue().size() == 1)
                .map(entry -> entry.getKey()) // 获得 entry 的键(重复元素)对应的 Stream
                .collect(Collectors.toList()); // 转化为 List

    }

    //查找对象中某个原属去重后的集合 [上海, 武汉, 北京, 深圳]
    public static List<String> getElementsAfterDuplicate(List<City> list) {
        return list.stream().map(o->o.getCity()).distinct().collect(Collectors.toList());
    }

    //对象中某个原属重复的 对象集合
    // [[City(city=上海, total=11), City(city=上海, total=33)], [City(city=武汉, total=22), City(city=武汉, total=55)]]
    public static List<List<City>> getDuplicateObject(List<City> list) {
        return list.stream().collect(Collectors.groupingBy(City::getCity)).entrySet().stream()
                .filter(entry -> entry.getValue().size() > 1) // >1 查找重复的集合;== 查找不重复的集合
                .map(entry -> entry.getValue())
                .collect(Collectors.toList());
    }

    //对象中某个原属未重复 对象集合
    //[[City(city=深圳, total=43)], [City(city=北京, total=33)]]
    public static List<City> getNoDuplicateObject(List<City> list) {
        List<City> cities = new ArrayList<>();
        list.stream().collect(Collectors.groupingBy(City::getCity)).entrySet().stream()
                    .filter(entry -> entry.getValue().size() ==1) //>1 查找重复的集合;== 查找不重复的集合;
                    .map(entry -> entry.getValue())
                    .forEach(p -> cities.addAll(p));
        return cities;
    }

    //根据对象的某个原属去重后的 对象集合
    //[City(city=上海, total=11), City(city=武汉, total=22), City(city=北京, total=33), City(city=深圳, total=43)]
    public static List<City> distinctObject(List<City> list) {
        return list.stream().filter(distinctByKey(City::getCity)).collect(Collectors.toList());
    }

    public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return object -> seen.putIfAbsent(keyExtractor.apply(object), Boolean.TRUE) == null;
    }

	//对list对某一属性相同去重,保留其他属性值最大的对象
	//假设有一个对象类 Obj,其中有属性 id、name、value,需要对 id 相同的对象进行去重,保留 value 最大的对象。可以使用 Java8 的流和 lambda 表达式完成这个操作:
	List<Obj> list; // 初始化 list
	List<Obj> result = list.stream().collect(Collectors.toMap(Obj::getId, Function.identity(), (obj1, obj2) -> obj1.getValue() > obj2.getValue() ? obj1 : obj2)).values().stream().collect(Collectors.toList());
	//上述代码中,首先将 list 转化为 Map,以 id 为键、Obj 对象为值,如果遇到重复的键时使用 merge 函数将其 value 值较大的对象作为值;然后获取 Map 的值集合并转化为 List,即为去重后的结果。
}

8、求两个集合的交集、差集、并集

List<Integer> typeList = Lists.newArrayList(1,2,3);
        List<Integer> collect = Lists.newArrayList(3,4,5);
        //求交集 - 存在,当前已选
        List<Integer> intersection = typeList.stream().filter(collect::contains).collect(Collectors.toList());
        System.out.println("存在,当前已选:"+intersection);
        //求差集 - 不存在,当前已选
        List<Integer> noExits = typeList.stream().filter(t -> !collect.contains(t)).collect(Collectors.toList());
        System.out.println("不存在,当前已选:"+noExits);
        //求差集 - 存在,当前未选
        List<Integer> exits = collect.stream().filter(t -> !typeList.contains(t)).collect(Collectors.toList());
        System.out.println("存在,当前未选:"+exits);
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值