[基础篇]-java8之List全面操作指南

List集合是开发中常用的集合之一,本文主要讲解List集合之各种操作与转换。

大致包含以下内容:

  • 遍历(5种方式)
  • 排序(普通排序、单/多属性排序)
  • 转Map
  • 分组
  • 去重(对象属性去重)
  • 提取
  • 过滤(单条件、多条件)
  • 取值(平均值、最大/最小值、求和)

前期准备

/**
 *  测试类
 *  @author 程序员小强
 */
@Data
public class Student {

    /**
     * id
     */
    private int id;
    /**
     * 姓名
     */
    private String name;
    /**
     * 年龄
     */
    private int age;

    /**
     * 性别 1-男 2-女
     */
    private int sex;

    /**
     * 手机
     */
    private String phone;

    /**
     * 创建时间
     */
    private Date createTime;

    public Student(int id, String name, int age, int sex, String phone, String createTime) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.phone = phone;
        this.createTime = parseDate(createTime);
    }

    /**
     * 时间格式
     */
    private SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 格式化时间
     *
     * @param dateStr
     */
    private Date parseDate(String dateStr) {
        try {
            return df.parse(dateStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Date();
    }
}

测试数据

private static List<Student> studentList = new ArrayList<Student>();

static {
    studentList.add(new Student(1, "张三", 11, 1, "13333345671", "2020-07-15 10:00:00"));
    studentList.add(new Student(2, "李四", 10, 1, "13333345672", "2020-07-16 10:00:00"));
    studentList.add(new Student(3, "王五", 12, 1, "13333345673", "2020-07-17 10:00:00"));
    studentList.add(new Student(4, "赵六", 11, 2, "13333345674", "2020-07-18 10:00:00"));
    studentList.add(new Student(5, "大黑", 13, 2, "13333345675", "2020-07-20 10:00:00"));
    studentList.add(new Student(6, "大白", 10, 2, "13333345676", "2020-07-20 10:00:00"));
}

1.遍历

java 8

//方式一.java 8   Lambda 遍历,stu 代表List里的Student对象
STUDENT_LIST.forEach(stu -> {
    System.out.println(stu);
});

//方式二.java 8   Lambda 遍历,stu 代表List里的Student对象
STUDENT_LIST.forEach(System.out::println);


java8之前

//方式三. for Each 遍历
for (Student stu : STUDENT_LIST) {
    System.out.println(stu);
}

//方式四
for (int i = 0; i < studentList.size(); i++) {
    System.out.println(studentList.get(i));
}

//方式五. 迭代器遍历
Iterator<Student> iterator = studentList.iterator();
while (iterator.hasNext()) {
    Student next = iterator.next();
    System.out.println(next);
}


2.排序

2.1普通集合

//普通list
List<Integer> ids = new ArrayList<Integer>() {{
    add(1);
    add(5);
    add(8);
    add(3);
}};
//升序
Collections.sort(ids);
//降序
ids.sort(Comparator.reverseOrder());

2.2对象集合

2.2.1单属性排序

// 1.根据年龄升序
List<Student> ageAscList = studentList.stream()
    .sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList());

// 2.根据年龄降序
List<Student> ageDescList = studentList.stream()
    .sorted(Comparator.comparing(Student::getAge).reversed()).collect(Collectors.toList());

2.2.2多属性排序

//根据年龄正序且创建时间倒叙
List<Student> sortedByAgeAndTime1 = studentList.stream()
               .sorted(Comparator.comparing(Student::getAge).
                thenComparing(Student::getCreateTime,Comparator.reverseOrder()))
                .collect(Collectors.toList());

2.2.2多字段排序语法

1.属性一升序

list.stream().sorted(Comparator.comparing(::属性一));

2.属性一降序排序
注意:两种写法

// 写法一:先以属性一升序,结果再进行属性一降序
list.stream().sorted(Comparator.comparing(::属性一).reversed());

// 写法二:以属性一降序
list.stream().sorted(Comparator.comparing(::属性一,Comparator.reverseOrder()));

属性一升序,属性二升序

list.stream().sorted(Comparator.comparing(::属性一).thenComparing(::属性二));

属性一升序,属性二降序

list.stream().sorted(Comparator.comparing(::属性一)
                     .thenComparing(::属性二,Comparator.reverseOrder()))

属性一降序,属性二升序

// 写法一:先以属性一升序,升序结果进行属性一降序,再进行属性二升序
list.stream().sorted(Comparator.comparing(::属性一).reversed().thenComparing(::属性二));

// 写法二:先以属性一降序,再进行属性二升序
list.stream().sorted(Comparator.comparing(::属性一,Comparator.reverseOrder()).thenComparing(::属性二));
 

属性一降序,属性二降序

// 写法一:先以属性一升序,升序结果进行属性一降序,再进行属性二降序
list.stream().sorted(Comparator.comparing(::属性一).reversed().thenComparing(::属性二,Comparator.reverseOrder()));

// 写法二:先以属性一降序,再进行属性二降序 
list.stream().sorted(Comparator.comparing(::属性一,Comparator.reverseOrder()).thenComparing(::属性二,Comparator.reverseOrder()));
 


综上实例可以总结两种写法

  • Comparator.comparing(类::属性一).reversed(); 得到排序结果后再排序
  • Comparator.comparing(类::属性一,Comparator.reverseOrder());是直接进行排序

两种排序是完全不一样的, 一定要区分开来,第二种更好理解,更推荐使用。

3.转Map


/**
 * List -> Map
 * 需要注意的是:toMap 如果集合对象有重复的key,会报错Duplicate key ....
 * 可以用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
 */
Map<Integer, Student> userMap = studentList.stream()
    .collect(Collectors.toMap(Student::getAge, a -> a, (k1, k2) -> k1));

4.分组

//根据年龄分组
Map<Integer, List<Student>> result =
   studentList.stream().collect(Collectors.groupingBy(Student::getAge));

5.去重

5.1普通集合

List<String> stringList = new ArrayList<String>() {{
    add("A");
    add("A");
    add("B");
    add("B");
    add("C");
}};
//去重后
stringList = stringList.stream().distinct().collect(Collectors.toList());

5.1对象属性去重

//根据年龄去重
List<Student>  resultList = studentList.stream().collect(
    Collectors.collectingAndThen(Collectors.toCollection(() 
    -> new TreeSet<>(Comparator.comparing(Student::getAge))), ArrayList::new));

注意:

  • import static java.util.stream.Collectors.collectingAndThen;
  • import static java.util.stream.Collectors.toCollection;
  • 通过 TreeSet<> 来达到获取不同元素的效果;

6.提取

//提取年龄
List<Integer> studentAgeList = studentList.stream()
    .map(Student::getAge) //流转化为Integer,方法引用写法,即使用 Student中 getAge() 方法
    .distinct() // 去重 处理
    .collect(Collectors.toList()); //输出流收集回List中,为空的情况下返回空集合

# 7.过滤

7.1单条件过滤

//过滤出 <13 的学生
List<Student> studentFilterList = studentList.stream()
    .filter(student -> student.getAge() < 13) // 只过滤出 <13 的学生
    .collect(Collectors.toList()); //输出流收集回List中,为空的情况下返回空集合

7.1多条件过滤

List<Student> studentFilterList = studentList.stream()
    .filter(stu -> { //多种条件过滤
        if (10 == stu.getAge() && "大白".equals(stu.getName())) {
            return true;
        }
        return false;
    }).collect(Collectors.toList()); //输出流收集回List中,为空的情况下返回空集合

8.取值

8.1平均数

// 平均数
double asDouble = studentList.stream().mapToLong(Student::getAge).average().getAsDouble();
System.out.println("average:" + asDouble);

double avg = studentList.stream().collect(Collectors.averagingLong(Student::getAge));
System.out.println("average:" + avg);

8.2最大值

// 最大值
long asLong = studentList.stream().mapToLong(Student::getAge).max().getAsLong();
System.out.println("max:" + asLong);

8.3最小值

// 最小值
long asLong1 = studentList.stream().mapToLong(Student::getAge).min().getAsLong();
System.out.println("min:" + asLong1);

8.4求和

// 求年龄和
long sum1 = studentList.stream().mapToLong(Student::getAge).sum();
System.out.println("sum:" + sum1);

关注程序员小强公众号更多编程趣事,知识心得与您分享
在这里插入图片描述

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值