java中list、map、array、实体类、字符串之间的相互转换,以及java8 stream使用

本文详细介绍了Java中list、map、array、实体类与字符串之间的转换方法,包括list与字符串互转、list转map、map转list、list与array互转、map与字符串互转。此外,还探讨了Java8 Stream的使用,如list排序、去重、根据字段操作等实用技巧。文章引用了多个博主的资源作为参考。

1.list与字符串互转

// 导入阿里的fastJson.jar
<!--添加fastjson依赖-->
 <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>fastjson</artifactId>
     <version>1.2.7</version>
 </dependency>


// 其中JSONObject和JSONArray均是继承JSON的方法,所以建议直接使用JSON抽象类即可
// list转换为json(以下六种均可)
List<User> list = new ArrayList<User>();
String str = JSON.toJSON(list).toString();
String str1 = JSON.toJSONString(list);
String str2 = JSONArray.toJSON(list).toString();
String str3 = JSONArray.toJSONString(list);
String str4 = JSONObject.toJSON(list).toString();
String str5 = JSONObject.toJSONString(list);
// json转换为list(以下三种均可)
List<User> list = JSONObject.parseArray(str, User.class);
List<User> list1 = JSON.parseArray(str, User.class);
List<User> list2 = JSONArray.parseArray(str, User.class);

实体类与字符串的转换与这个上面类似

String str = JSON.toJSONString(new User()); // 转字符串
User user = JSON.parseObject(str, User.class); // 转实体类

2-1.list转map

lombok注解链接

    // 这里的注解作用可点击上方链接
    @Data
    @Accessors(chain = true)
    @AllArgsConstructor
    @NoArgsConstructor
    public static class User{
        private String id;
        private String name;
    }


		// list转map
		// ::用于类与方法之间,如person -> person.getAge();可以替换成Person::getAge
        List<User> userList = Lists.newArrayList(
                new User().setId("A").setName("张三"),
                new User().setId("B").setName("李四"), 
                new User().setId("C").setName("王五")
        );
        Map<String,String> map =  userList.stream().collect(Collectors.toMap(User::getId, User::getName));
        System.out.println(map);


{A=张三, B=李四, C=王五}

其中Collectors.toMap 有三个重载方

<think>我们有一个需求:在使用MyBatisPlus时,查询数据库中以字符串数组格式存储的数据,并正确映射到实体类中。根据提供的引用,我们可以知道:1.如果数据库是PostgreSQL,它支持数组类型,我们可以使用ArrayTypeHandler(引用[1])。2.另一种情况是数据库存储的是字符串(比如逗号分隔的字符串),我们需要将其转换为数组。这时我们可以自定义一个TypeHandler(引用[2]中提到了转换,但未给出具体实现,我们可以参考类似思想)。但是,引用[3]和[4]也提供了一些思路:3.使用@TableField注解的typeHandler属性指定自定义的类型处理器(引用[1]和[3]都用了这个方式)。4.引用[4]提到了PG数据库支持数组类型和jsonb格式,但我们的需求是字符串数组。因此,我们有两种情况:情况1:数据库字段是数组类型(如PostgreSQL的数组类型)使用ArrayTypeHandler(如果MyBatisPlus自带的话,或者自定义一个,但引用[1]中使用ArrayTypeHandler,所以我们可以尝试使用MyBatisPlus提供的或者自定义)情况2:数据库字段是字符串类型(如varchar),存储的是逗号分隔的字符串(或其他分隔符)我们需要自定义一个TypeHandler,将字符串按照分隔符拆分成数组。由于问题中没有明确数据库类型,我们将分别说明两种常见情况。步骤:1.对于PostgreSQL数组类型:在实体类中,使用@TableField注解指定typeHandler为ArrayTypeHandler(注意:MyBatisPlus是否内置了针对PG数组的ArrayTypeHandler?实际上,MyBatisPlus并没有内置,但我们可以使用MyBatis提供的org.apache.ibatis.type.ArrayTypeHandler,但注意这个是为JDBC的ARRAY类型设计的,而PG的数组可以用ARRAY类型。另外,引用[1]中使用ArrayTypeHandler,所以我们假设可以这样用)2.对于字符串类型(以逗号分隔为例):我们需要自定义一个TypeHandler,将数据库中的字符串转换成String[]。下面分别给出示例:情况一:PostgreSQL数组类型假设表结构:CREATETABLEstudent(idSERIALPRIMARYKEY,nameVARCHAR(100),hobbiesTEXT[]--或者VARCHAR[],表示数组类型);实体类:@Data@TableName("student")publicclassStudent{privateIntegerid;privateStringname;//使用ArrayTypeHandler,注意:这里hobbies是String数组@TableField(typeHandler=ArrayTypeHandler.class)privateString[]hobbies;}但是,请注意:MyBatis自带的ArrayTypeHandler(在org.apache.ibatis.type包下)是用于处理java.sql.Array的,而PG的数组在JDBC中会被映射为java.sql.Array。但我们的实体类字段是String[],所以我们需要一个能处理String数组的TypeHandler。实际上,MyBatis自带的ArrayTypeHandler会将java.sql.Array转换成Object[],然后我们可以将其转换为String[],但这样并不直接。因此,我们可能需要为PG的字符串数组自定义一个TypeHandler。或者,我们可以使用MyBatisPlus提供的PgArrayTypeHandler(如果存在的话)。但MyBatisPlus目前并没有提供针对PG数组的TypeHandler,所以我们可以自定义一个。自定义TypeHandler(针对PostgreSQL的字符串数组)示例:publicclassStringArrayTypeHandlerextendsBaseTypeHandler<String[]>{@OverridepublicvoidsetNonNullParameter(PreparedStatementps,inti,String[]parameter,JdbcTypejdbcType)throwsSQLException{//创建PG的数组Connectionconn=ps.getConnection();Arrayarray=conn.createArrayOf("varchar",parameter);ps.setArray(i,array);}@OverridepublicString[]getNullableResult(ResultSetrs,StringcolumnName)throwsSQLException{Arrayarray=rs.getArray(columnName);if(array==null){returnnull;}return(String[])array.getArray();}@OverridepublicString[]getNullableResult(ResultSetrs,intcolumnIndex)throwsSQLException{Arrayarray=rs.getArray(columnIndex);if(array==null){returnnull;}return(String[])array.getArray();}@OverridepublicString[]getNullableResult(CallableStatementcs,intcolumnIndex)throwsSQLException{Arrayarray=cs.getArray(columnIndex);if(array==null){returnnull;}return(String[])array.getArray();}}然后在实体类使用:@TableField(typeHandler=StringArrayTypeHandler.class)privateString[]hobbies;情况二:数据库字段是普通字符串(如varchar),存储逗号分隔的字符串例如,表结构:CREATETABLEstudent(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(100),hobbiesVARCHAR(255)--存储类似"READ,SPORT,MUSIC");我们需要自定义一个TypeHandler,将字符串按逗号分割成数组:publicclassStringToArrayTypeHandlerextendsBaseTypeHandler<String[]>{@OverridepublicvoidsetNonNullParameter(PreparedStatementps,inti,String[]parameter,JdbcTypejdbcType)throwsSQLException{//将数组转成逗号分隔的字符串Stringresult=String.join(",",parameter);ps.setString(i,result);}@OverridepublicString[]getNullableResult(ResultSetrs,StringcolumnName)throwsSQLException{Stringvalue=rs.getString(columnName);returnvalue==null?null:value.split(",");}@OverridepublicString[]getNullableResult(ResultSetrs,intcolumnIndex)throwsSQLException{Stringvalue=rs.getString(columnIndex);returnvalue==null?null:value.split(",");}@OverridepublicString[]getNullableResult(CallableStatementcs,intcolumnIndex)throwsSQLException{Stringvalue=cs.getString(columnIndex);returnvalue==null?null:value.split(",");}}实体类:@Data@TableName("student")publicclassStudent{privateIntegerid;privateStringname;@TableField(typeHandler=StringToArrayTypeHandler.class)privateString[]hobbies;}注意:这里的分隔符是逗号,如果实际使用其他分隔符,请修改split的表达式。另外,引用[2]中提到了从数据库读取数据时,调用set方法进行转换,其实就是通过TypeHandler实现的。总结:根据数据库字段的实际类型,选择使用不同的TypeHandler:-如果是PostgreSQL的数组类型,可以使用自定义的StringArrayTypeHandler(如上所示)或者使用MyBatis的ArrayTypeHandler(但需要处理类型转换)。-如果是普通字符串类型,则使用自定义的StringToArrayTypeHandler。同时,请注意,在MyBatisPlus的配置中,如果使用了自定义TypeHandler,确保它被正确扫描或配置。在SpringBoot中,通常将TypeHandler放在扫描包路径下即可。另外,引用[3]中提到了在@TableField中使用typeHandler,并且实体类上@TableName设置autoResultMap=true,但根据MyBatisPlus文档,autoResultMap用于自动生成resultMap,当有typeHandler时建议设置autoResultMap=true以确保结果映射正确。所以,我们可以在实体类上加上@TableName(autoResultMap=true)。示例:@TableName(value="student",autoResultMap=true)publicclassStudent{//...其他字段@TableField(typeHandler=StringToArrayTypeHandler.class)//或者StringArrayTypeHandlerprivateString[]hobbies;}这样,在使用MyBatisPlus的BaseMapper进行查询时,就可以正确映射数组字段了。注意事项:1.自定义TypeHandler需要确保正确处理null值。2.在插入或更新时,TypeHandler也会将数组转换成数据库对应的格式。如果数据库字段类型和TypeHandler不匹配,可能会出现转换错误。因此,请根据实际数据库字段类型选择合适的TypeHandler。最后,我们也可以参考引用[1]中的示例,它使用ArrayTypeHandler,但注意它针对的是PG的数组类型。因此,请根据实际情况选择方案。</think>### MyBatisPlus 查询字符串数组字段映射到实体类 在 MyBatisPlus 中,将数据库中的字符串数组格式字段映射到实体类,主要通过**自定义类型处理器(TypeHandler)** 实现。以下是两种常见场景的解决方案: --- #### 场景1:数据库字段为字符串(如逗号分隔值) 若数据库存储的是逗号分隔的字符串(如 `"READ,SPORT,MUSIC"`),需自定义 `TypeHandler` 实现字符串与数组的转换。 ##### 步骤: 1. **创建自定义 TypeHandler** ```java public class StringArrayTypeHandler extends BaseTypeHandler<String[]> { @Override public void setNonNullParameter(PreparedStatement ps, int i, String[] parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, String.join(",", parameter)); // 数组 → 逗号分隔字符串 } @Override public String[] getNullableResult(ResultSet rs, String columnName) throws SQLException { String value = rs.getString(columnName); return value != null ? value.split(",") : null; // 字符串 → 数组 } @Override public String[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String value = rs.getString(columnIndex); return value != null ? value.split(",") : null; } @Override public String[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String value = cs.getString(columnIndex); return value != null ? value.split(",") : null; } } ``` 2. **实体类配置 TypeHandler** ```java @Data @TableName(autoResultMap = true) // 启用自动结果映射 public class Student { private Long id; @TableField(value = "hobbies", typeHandler = StringArrayTypeHandler.class) private String[] hobbies; // 映射到字符串数组 } ``` 3. **查询时自动转换** ```java // 使用MyBatisPlus查询,自动触发转换 Student student = studentMapper.selectById(1); System.out.println(Arrays.toString(student.getHobbies())); // 输出: ["READ", "SPORT", "MUSIC"] ``` --- #### 场景2:数据库支持原生数组类型(如 PostgreSQL) 若数据库支持数组类型(如 PostgreSQL 的 `TEXT[]`),使用 **`ArrayTypeHandler`** 或自定义处理器。 ##### 步骤: 1. **实体类配置(PostgreSQL 示例)** ```java @Data @TableName(value = "student", autoResultMap = true) public class Student { private Long id; // 使用MyBatisPlus内置的ArrayTypeHandler @TableField(typeHandler = ArrayTypeHandler.class) private String[] hobbies; // 映射到PG数组 } ``` 2. **插入数据示例** ```java Student student = new Student(); student.setHobbies(new String[]{"READ", "MUSIC"}); studentMapper.insert(student); // 自动转换为PG数组格式 ``` --- ### 关键注意事项 1. **启用结果映射** 实体类需添加 `@TableName(autoResultMap = true)`,否则 `TypeHandler` 不生效[^3]。 2. **兼容性处理** - 字符串分隔符需一致(如逗号、分号)。 - 空值处理:在 `TypeHandler` 中判断 `null` 和空字符串。 3. **复杂类型扩展** 如需映射 `List<Enum>`,可在 `TypeHandler` 中实现枚举转换: ```java // 示例:将字符串转换为枚举数组 Arrays.stream(value.split(",")) .map(Hobby::valueOf) // 转为枚举 .toArray(Hobby[]::new); ``` 4. **查询时指定 TypeHandler** 若需在 XML 查询中强制使用: ```xml <result column="hobbies" property="hobbies" typeHandler="com.example.StringArrayTypeHandler"/> ``` --- ### 示例完整流程 **实体类** → **TypeHandler转换** → **数据库读写** ```mermaid graph LR A[实体类 String[] hobbies] -->|写入时| B[TypeHandler 转字符串] B --> C[数据库 VARCHAR 字段] C -->|读取时| B B --> A ``` 通过上述配置,MyBatisPlus 可自动完成数据库字符串Java 数组的双向转换[^2][^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值