【工作中问题解决实践 八】工作中常用的集合操作

简介: 【工作中问题解决实践 八】工作中常用的集合操作

工作中常用到一些集合的操作,Java8的新特性提供了stream的流操作,大大方便了集合的使用,这里详细总结下日常用的一些操作,下次用到的时候拿来即用,以备遗忘,同时自己也实现一遍,这样印象更深刻些

要操作的对象

首先定义要操作的对象代码清单,包括人员信息

package com.example.springboot.jackson;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
 * The type Person.
 *
 * @author tianmaolin004
 * @date 2023 /3/18
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    private String name;
    private Integer age;
    private List<String> interests;
    private Map<String,Integer> scores;
    private Set<String> loveMovies;
    private LocalDate birthday;
    private String school;
}

和学校信息:

package com.example.springboot.jackson;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * @author tianmaolin004
 * @date 2023/3/19
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class School {
    private String school;
}

原始数据准备

要操作的集合原始数据准备:

Person person1 = Person.builder()
                .name("tml")
                .age(24)
                .school("CUB")
                .build();
        Person person2 = Person.builder()
                .name("gcy")
                .age(23)
                .school("ZENDX")
                .build();
        Person person3 = Person.builder()
                .name("wc")
                .age(28)
                .school("CUB")
                .build();
        List<Person> personList = new ArrayList<>();
        personList.add(person1);
        personList.add(person2);
        personList.add(person3);
        System.out.println("原始集合=====================================");
        System.out.println(personList);

集合常用操作

集合的常用操作分为5部分

1 LIST集合相关用法

操作代码如下

// 1 LIST集合相关用法
        System.out.println("");
        System.out.println("LIST集合相关用法=====================================");
        System.out.println("filter用法");
        List<Person> filter = personList.stream().filter(x -> x.getSchool().equals("CUB")).collect(Collectors.toList());
        System.out.println(filter);
        System.out.println("map用法");
        List<Integer> map = personList.stream().map(Person::getAge).collect(Collectors.toList());
        System.out.println(map);
        System.out.println("sort用法");
        List<Person> sort = personList.stream().sorted(Comparator.comparing(Person::getAge)).collect(Collectors.toList());
        System.out.println(sort);
        System.out.println("limit用法");
        List<Person> limit = personList.stream().limit(1).collect(Collectors.toList());
        System.out.println(limit);
        System.out.println("limit深拷贝用法");
        List<Person> deepCopy = JsonUtils.deepCopy(personList, new TypeReference<List<Person>>() {
        });
        System.out.println(deepCopy);
        System.out.println("remove用法");
        deepCopy.removeIf(x -> x.getAge().equals(28));
        System.out.println(deepCopy);

运行结果如下

2 LIST转LIST相关用法

操作代码如下

System.out.println("");
        System.out.println("LIST转LIST=====================================");
        List<School> schools = personList.stream().map(x -> {
            School school = new School();
            school.setSchool(x.getSchool());
            return school;
        }).collect(Collectors.toList());
        System.out.println(schools);

运行结果如下

3 LIST转MAP相关用法

操作代码如下

//3 LIST转Map
        System.out.println("");
        System.out.println("LIST转Map=====================================");
        System.out.println("list按照分组转Map用法");
        Map<String, List<Person>> listConvertMap = personList.stream().collect(Collectors.groupingBy(Person::getSchool));
        System.out.println(listConvertMap);
        System.out.println("list按照对象字段转Map用法");
        Map<String, Person> listFieldMap = personList.stream().collect(Collectors.toMap(Person::getName, x -> x));
        System.out.println(listFieldMap);
        System.out.println("list按照对象抽离字段字段转Map用法");
        Map<String, String> listGetFieldMap = personList.stream().collect(Collectors.toMap(Person::getName, Person::getSchool));
        System.out.println(listGetFieldMap);

运行结果如下

4 MAP集合相关用法相关用法

操作代码如下

// 4 Map集合相关用法
        System.out.println("");
        System.out.println("Map集合相关用法=====================================");
        System.out.println(personList);
        System.out.println("遍历Map用法");
        listConvertMap.forEach((x, y) -> {
            if (x.equals("CUB")) {
                Set<String> loveMovies = new HashSet<>();
                loveMovies.add("士兵突击");
                loveMovies.add("士兵突击");
                loveMovies.add("爱乐之城");
                y.stream().forEach(t -> t.setLoveMovies(loveMovies));
            }
        });
        System.out.println(listConvertMap);

运行结果如下

5 字符串集合相关操作

操作代码如下

// 5 字符串集合相关操作
        System.out.println("");
        System.out.println("字符串集合相关操作=====================================");
        List<String> strings = Arrays.asList("abc", "", "abc", "efg", "add", "", "jkl");
        String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
        System.out.println("合并字符串: " + mergedString);
        String mergedDistinctString = strings.stream().filter(string -> !string.isEmpty()).distinct().collect(Collectors.joining(", "));
        System.out.println("合并去重字符串: " + mergedDistinctString);
        String[] strConvertList = StringUtils.split(mergedDistinctString, ",");
        System.out.println("字符串转集合:" + Arrays.asList(strConvertList));
        List<List<String>> parts = Lists.partition(strings, 2);
        System.out.println("字符串分组: " + parts);
        parts.forEach(System.out::println);

运行结果如下

全部操作代码清单

集合常用操作测试代码如下:

package com.example.springboot.jackson;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author tianmaolin004
 * @date 2023/3/18
 */
public class ListTest {
    public static void main(String[] args) {
        Person person1 = Person.builder()
                .name("tml")
                .age(24)
                .school("CUB")
                .build();
        Person person2 = Person.builder()
                .name("gcy")
                .age(23)
                .school("ZENDX")
                .build();
        Person person3 = Person.builder()
                .name("wc")
                .age(28)
                .school("CUB")
                .build();
        List<Person> personList = new ArrayList<>();
        personList.add(person1);
        personList.add(person2);
        personList.add(person3);
        System.out.println("原始集合=====================================");
        System.out.println(personList);
        // 1 LIST集合相关用法
        System.out.println("");
        System.out.println("LIST集合相关用法=====================================");
        System.out.println("filter用法");
        List<Person> filter = personList.stream().filter(x -> x.getSchool().equals("CUB")).collect(Collectors.toList());
        System.out.println(filter);
        System.out.println("map用法");
        List<Integer> map = personList.stream().map(Person::getAge).collect(Collectors.toList());
        System.out.println(map);
        System.out.println("sort用法");
        List<Person> sort = personList.stream().sorted(Comparator.comparing(Person::getAge)).collect(Collectors.toList());
        System.out.println(sort);
        System.out.println("limit用法");
        List<Person> limit = personList.stream().limit(1).collect(Collectors.toList());
        System.out.println(limit);
        System.out.println("limit深拷贝用法");
        List<Person> deepCopy = JsonUtils.deepCopy(personList, new TypeReference<List<Person>>() {
        });
        System.out.println(deepCopy);
        System.out.println("remove用法");
        deepCopy.removeIf(x -> x.getAge().equals(28));
        System.out.println(deepCopy);
        //2 LIST转LIST
        System.out.println("");
        System.out.println("LIST转LIST=====================================");
        List<School> schools = personList.stream().map(x -> {
            School school = new School();
            school.setSchool(x.getSchool());
            return school;
        }).collect(Collectors.toList());
        System.out.println(schools);
        //3 LIST转Map
        System.out.println("");
        System.out.println("LIST转Map=====================================");
        System.out.println("list按照分组转Map用法");
        Map<String, List<Person>> listConvertMap = personList.stream().collect(Collectors.groupingBy(Person::getSchool));
        System.out.println(listConvertMap);
        System.out.println("list按照对象字段转Map用法");
        Map<String, Person> listFieldMap = personList.stream().collect(Collectors.toMap(Person::getName, x -> x));
        System.out.println(listFieldMap);
        System.out.println("list按照对象抽离字段字段转Map用法");
        Map<String, String> listGetFieldMap = personList.stream().collect(Collectors.toMap(Person::getName, Person::getSchool));
        System.out.println(listGetFieldMap);
        // 4 Map集合相关用法
        System.out.println("");
        System.out.println("Map集合相关用法=====================================");
        System.out.println(personList);
        System.out.println("遍历Map用法");
        listConvertMap.forEach((x, y) -> {
            if (x.equals("CUB")) {
                Set<String> loveMovies = new HashSet<>();
                loveMovies.add("士兵突击");
                loveMovies.add("士兵突击");
                loveMovies.add("爱乐之城");
                y.stream().forEach(t -> t.setLoveMovies(loveMovies));
            }
        });
        System.out.println(listConvertMap);
        // 5 字符串集合相关操作
        System.out.println("");
        System.out.println("字符串集合相关操作=====================================");
        List<String> strings = Arrays.asList("abc", "", "abc", "efg", "add", "", "jkl");
        String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
        System.out.println("合并字符串: " + mergedString);
        String mergedDistinctString = strings.stream().filter(string -> !string.isEmpty()).distinct().collect(Collectors.joining(", "));
        System.out.println("合并去重字符串: " + mergedDistinctString);
        String[] strConvertList = StringUtils.split(mergedDistinctString, ",");
        System.out.println("字符串转集合:" + Arrays.asList(strConvertList));
        List<List<String>> parts = Lists.partition(strings, 2);
        System.out.println("字符串分组: " + parts);
        parts.forEach(System.out::println);
    }
}

运行结果如下:

原始集合=====================================
[Person(name=tml, age=24, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB), Person(name=gcy, age=23, interests=null, scores=null, loveMovies=null, birthday=null, school=ZENDX), Person(name=wc, age=28, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB)]
LIST集合相关用法=====================================
filter用法
[Person(name=tml, age=24, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB), Person(name=wc, age=28, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB)]
map用法
[24, 23, 28]
sort用法
[Person(name=gcy, age=23, interests=null, scores=null, loveMovies=null, birthday=null, school=ZENDX), Person(name=tml, age=24, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB), Person(name=wc, age=28, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB)]
limit用法
[Person(name=tml, age=24, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB)]
limit深拷贝用法
[Person(name=tml, age=24, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB), Person(name=gcy, age=23, interests=null, scores=null, loveMovies=null, birthday=null, school=ZENDX), Person(name=wc, age=28, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB)]
remove用法
[Person(name=tml, age=24, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB), Person(name=gcy, age=23, interests=null, scores=null, loveMovies=null, birthday=null, school=ZENDX)]
LIST转LIST=====================================
[School(school=CUB), School(school=ZENDX), School(school=CUB)]
LIST转Map=====================================
list按照分组转Map用法
{CUB=[Person(name=tml, age=24, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB), Person(name=wc, age=28, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB)], ZENDX=[Person(name=gcy, age=23, interests=null, scores=null, loveMovies=null, birthday=null, school=ZENDX)]}
list按照对象字段转Map用法
{tml=Person(name=tml, age=24, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB), wc=Person(name=wc, age=28, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB), gcy=Person(name=gcy, age=23, interests=null, scores=null, loveMovies=null, birthday=null, school=ZENDX)}
list按照对象抽离字段字段转Map用法
{tml=CUB, wc=CUB, gcy=ZENDX}
Map集合相关用法=====================================
[Person(name=tml, age=24, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB), Person(name=gcy, age=23, interests=null, scores=null, loveMovies=null, birthday=null, school=ZENDX), Person(name=wc, age=28, interests=null, scores=null, loveMovies=null, birthday=null, school=CUB)]
遍历Map用法
{CUB=[Person(name=tml, age=24, interests=null, scores=null, loveMovies=[士兵突击, 爱乐之城], birthday=null, school=CUB), Person(name=wc, age=28, interests=null, scores=null, loveMovies=[士兵突击, 爱乐之城], birthday=null, school=CUB)], ZENDX=[Person(name=gcy, age=23, interests=null, scores=null, loveMovies=null, birthday=null, school=ZENDX)]}
Map转List用法
字符串集合相关操作=====================================
合并字符串: abc, abc, efg, add, jkl
合并去重字符串: abc, efg, add, jkl
字符串转集合:[abc,  efg,  add,  jkl]
字符串分组: [[abc, ], [abc, efg], [add, ], [jkl]]
[abc, ]
[abc, efg]
[add, ]
[jkl]
Process finished with exit code 0

深拷贝相关代码如下:

package com.example.springboot.jackson;
import com.alibaba.druid.util.StringUtils;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
 * The type Json operator.
 *
 * @author tianmaolin004
 * @date 2023 /3/18
 */
@Slf4j
public class JsonUtils {
    private static final ObjectMapper objectMapper = new ObjectMapper();
    private static final String LOCAL_DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    static {
        // 1 序列化及反序列化的时间配置
        JavaTimeModule timeModule = new JavaTimeModule();
        timeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ISO_LOCAL_DATE));
        timeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ISO_LOCAL_DATE));
        timeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ISO_LOCAL_TIME));
        timeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ISO_LOCAL_TIME));
        timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(LOCAL_DATE_TIME_PATTERN)));
        timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(LOCAL_DATE_TIME_PATTERN)));
        objectMapper.registerModule(timeModule);
        objectMapper.setDateFormat(new SimpleDateFormat(LOCAL_DATE_TIME_PATTERN));
        //2 忽略反序列化时,对象不存在对应属性的错误,如果不存在该属性,则设置值为null
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        //3 忽略序列化时值为Null元素,不存在该元素,则字符串中无该元素,而不是展示为null
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    }
    /**
     * 对象转字符串
     *
     * @param <T> the type parameter
     * @param obj the obj
     * @return the string
     */
    public static <T> String obj2Str(T obj) {
        if (obj == null) {
            return null;
        }
        try {
            return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
        } catch (Exception e) {
            log.error("obj2Str fail");
            return null;
        }
    }
    /**
     * 字符串转对象
     *
     * @param <T>   the type parameter
     * @param str   the str
     * @param clazz the clazz
     * @return the t
     */
    public static <T> T str2Obj(String str, Class<T> clazz) {
        if (StringUtils.isEmpty(str) || clazz == null) {
            return null;
        }
        try {
            return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);
        } catch (Exception e) {
            log.error("str2Obj fail");
            return null;
        }
    }
    /**
     * 字符串转对象:泛型模式,一般用于集合
     *
     * @param <T>           the type parameter
     * @param str           the str
     * @param typeReference the type reference
     * @return the t
     */
    public static <T> T str2Obj(String str, TypeReference<T> typeReference) {
        if (StringUtils.isEmpty(str) || typeReference == null) {
            return null;
        }
        try {
            return (T) (typeReference.getType().equals(String.class) ? str : objectMapper.readValue(str, typeReference));
        } catch (Exception e) {
            log.error("str2Obj fail");
            return null;
        }
    }
    /**
     * 字符串转JsonNode
     *
     * @param str the str
     * @return the json node
     */
    public static JsonNode str2JsonNode(String str) {
        if (StringUtils.isEmpty(str)) {
            return null;
        }
        try {
            return objectMapper.readTree(str);
        } catch (Exception e) {
            log.error("str2Obj fail");
            return null;
        }
    }
    /**
     * 对象互转
     *
     * @param <T>         the type parameter
     * @param fromValue   the from value
     * @param toValueType the to value type
     * @return the t
     */
    public static <T> T convertValue(@NonNull Object fromValue, @NonNull Class<T> toValueType) {
        try {
            return objectMapper.convertValue(fromValue, toValueType);
        } catch (Exception e) {
            log.error("str2Obj fail");
            return null;
        }
    }
    /**
     * 对象互转泛型模式
     *
     * @param <T>            the type parameter
     * @param fromValue      the from value
     * @param toValueTypeRef the to value type ref
     * @return the t
     */
    public static <T> T convertValue(@NonNull Object fromValue, @NonNull TypeReference<T> toValueTypeRef) {
        try {
            return objectMapper.convertValue(fromValue, toValueTypeRef);
        } catch (Exception e) {
            log.error("str2Obj fail");
            return null;
        }
    }
    /**
     * 集合深拷贝
     *
     * @param <T>      the type parameter
     * @param src      the src
     * @param dstClazz the dst clazz
     * @return the t
     */
    public static <T> T deepCopy(Object src,TypeReference<T> dstClazz) {
        if (null == src) {
            return null;
        }
        return JsonUtils.str2Obj(JsonUtils.obj2Str(src), dstClazz);
    }
}

总结一下

21年底的时候学习了一下Java8的新特性【Java新特性学习 四】JDK8: 库函数新特性之Optional,Streams,Date/Time API(JSR 310),Base64,并行数组,但同样只是大致了解了下,并未详细的使用和实验,如今发现工作中使用场景太多了,把这些常用的场景都记录下来,下次用的时候应该也比较方便了。

相关文章
|
14天前
|
数据可视化 数据管理 项目管理
职场打工人怎么记录日常工作?5款热门工具的优缺点分析
本文介绍了五款高效的工作记录工具,包括板栗看板、Miro、Airtable、Notion 和 Wrike,分别针对任务管理、创意协作、数据库管理、多功能笔记及跨团队协作等不同需求,通过对比它们的使用场景、优缺点及其适用性,帮助读者选择最适合自身需求的工具。
职场打工人怎么记录日常工作?5款热门工具的优缺点分析
|
2月前
|
缓存 安全 Java
分享几个工作中实用的代码优化技巧!
分享几个工作中实用的代码优化技巧!
分享几个工作中实用的代码优化技巧!
|
5月前
|
运维
开发与运维编程问题之命令式编程的优点如何解决
开发与运维编程问题之命令式编程的优点如何解决
|
7月前
|
搜索推荐
分享5款对工作学习有帮助的效率软件
今天再来推荐5个超级好用的效率软件,无论是对你的学习还是办公都能有所帮助,每个都堪称神器中的神器,用完后觉得不好用你找我。
57 6
|
敏捷开发 数据可视化 测试技术
如何做好敏捷迭代管理?过程及工具分享
Leangoo领歌是ScrumCN(scrum.cn)旗下的一款永久免费的敏捷研发管理工具。 Leangoo领歌覆盖了敏捷研发全流程,包括小型团队敏捷开发,Scrum of Scrums大规模敏捷以及SAFe大规模敏捷框架等,提供端到端敏捷研发管理解决方案,涵盖敏捷需求管理、任务协同、缺陷管理、测试管理、进展跟踪、统计度量等。领歌上手快、实施成本低,可帮助企业快速落地敏捷,提质增效、缩短周期、加速创新,在数字时代赢得竞争。
如何做好敏捷迭代管理?过程及工具分享
|
设计模式 SQL 分布式计算
快速适应工作之工作范式的寻找
快速适应工作之工作范式的寻找
118 0
|
XML SQL JavaScript
当前在工作中使用到的高效的代码编写方法
当前在工作中使用到的高效的代码编写方法,让代码去生成重复性质的代码
132 0
FXS与FXO:有什么区别以及它是如何工作的
出于显而易见的原因,切换到VoIP电话系统已成为许多中小型企业的热门选择。最常见的是更好的连接、扩展的通话功能和工具,以及拨打和接听本地和国际电话的可能性。在VoIP之前,普遍采用模拟电话系统,它们使用FXO和FXS端口建立连接。以及如何使用它们将模拟电话和PBX连接到VoIP系统,以构建混合通信基础设施并实现业务通信现代化。
|
缓存 安全 算法
在工作中常用到的集合有哪些?
作为一个新人,最关心的其实有一点:这个技术在工作中是怎么用的。换个说法:“工作中常用到的Java集合有哪些,应用场景是什么”
305 0
在工作中常用到的集合有哪些?
|
缓存 安全 Java
分享几个工作中实用的代码优化技巧!
前言之前分享一篇代码优化的文章:条件语句的多层嵌套问题优化,助你写出不让同事吐槽的代码!今天再次分享一些我日常工作中常用的代码优化技巧,希望对大家有帮助!文章首发在公众号(月伴飞鱼),之后同步到个人网站:xiaoflyfish.cn/觉得有收获,希望帮忙点赞,转发下哈,谢谢,谢谢正文类成员与方法的可见性最小化举例:如果是一个private的方法,想删除就删除如果一个public的service方法,或者一个public的成员变量,删除一下,不得思考很多。使用位移操作替代乘除法计算机是使用二进制表的位移操作会极大地提高性能。&lt;&lt; 左移相当于乘以 2;&gt;&gt; 右移相当于除以2,但它会忽略符号位,空位