List 中去除 null 方法讨论

先看下面的程序段:

 

public static void main(String[] args) {
	List<Integer> arrays = new ArrayList<Integer>();
	arrays.add(2);
	arrays.add(null);
	arrays.add(456);
	arrays.add(null);
	arrays.add(789);
	System.out.println(arrays);
}

 注:一个list,向其中插入数据时,也插入一些null。程序输出如下:

 

 

[2, null, 456, null, 789]

 现在有这个需求:去除list中null 元素。尝试的代码如下:

 

 

public static void main(String[] args) {
	List<Integer> arrays = new ArrayList<Integer>();
	arrays.add(2);
	arrays.add(null);
	arrays.add(456);
	arrays.add(null);
	arrays.add(789);
	arrays.remove(null);
	System.out.println(arrays);
}

 调用remove(object)方法,程序的输出如下:

 

 

[2, 456, null, 789]

 可以看出:只remove了第一个null元素。这不是我们期望的结果。继续找方法。考虑到有一个removeAll(Collection<?> c) ,尝试使用。代码如下:

 

 

public static void main(String[] args) {
	List<Integer> arrays = new ArrayList<Integer>();
	arrays.add(2);
	arrays.add(null);
	arrays.add(456);
	arrays.add(null);
	arrays.add(789);
	List<Integer> nullArr = new ArrayList<Integer>();
	nullArr.add(null);
	arrays.removeAll(nullArr);
	System.out.println(arrays);
}

 程序的输出如下:

 

 

[2, 456, 789]

 这是我们期望的结果。你可能会尝试下面这样使用:

 

 

arrays.removeAll(null);

 很遗憾,程序出错了:Exception in thread "main" java.lang.NullPointerException。

 

 到这里,我们似乎找到了解决问题的办法。但是,如果我们的系统中,有这种类型的List<E>,如List<TempProductDto>、List<merchantDto> 时,我们要从这些List中移除掉null,就要创建如下的代码:

 

List<TempProductDto> nullTempProd = new ArrayList<TempProductDto>(1);
nullTempProd.add(null);

List<MerchantDto> nullMerchant = new ArrayList<MerchantDto>(1);
nullMerchant.add(null);

 每种类型,就要创建对应类型的List,并把null 放入到List中。是不是很麻烦。能不能写个公用的Util类呢?以下是我写的Util 类:

 

 

import java.io.Serializable;
import java.util.AbstractList;
import java.util.RandomAccess;

public class NullCollection extends AbstractList<Object>
implements RandomAccess, Serializable  {

	private static final long serialVersionUID = 5206887786441397812L;

	@Override
	public Object get(int index) {
		return null;
	}

	@Override
	public int size() {
		return 1;
	}
	
	public boolean contains(Object obj) {
		return null == obj;
	}
	
	private Object readResolve() {
        return null;
    }
}

 

import java.util.Collection;
import java.util.List;

public class YHDCollectionUtils {
	
	 public static final Collection NULL_COLLECTION = new NullCollection();
		
	public static final <T> Collection<T> nullCollection() {
		return (List<T>) NULL_COLLECTION;
	}
}

 

 使用我写的util类进行测试。代码如下:

 

public static void main(String[] args) {
	List<Integer> arrays = new ArrayList<Integer>();
	arrays.add(2);
	arrays.add(null);
	arrays.add(456);
	arrays.add(null);
	arrays.add(789);
	arrays.removeAll(YHDCollectionUtils.nullCollection());
	System.out.println(arrays);
}

 执行结果如下:

 

 

[2, 456, 789]

 Util 类可以成功的去除List中的null元素。

 

 也许你会问:为什么要把null放入List中,只有2B青年会这么干?在一般业务中,我们确实不需要把null放入List中,但有一种场景:从页面封装的List,如下面的代码:

 

<input name="dto.productList[0].name" value="我是名称1">
<input name="dto.productList[0].price" value="我是价格1">

<input name="dto.productList[2].name" value="我是名称2">
<input name="dto.productList[2].price" value="我是价格2">

<input name="dto.productList[4].name" value="我是名称3">
<input name="dto.productList[4].price" value="我是价格3">

 OGNL 会自动把dto.productList[1]、dto.productList[3] 的object封装成null。因此,我们在操作dto.productList 前,优先把 productList 中null去除掉,防止 null 引起的空指针异常。

 最后,欢迎各位拍砖。

 

<think>好的,我现在需要帮助用户将Java中的String字符串转换为List<String>类型的列表。首先,我要回顾用户之前的问题和我的回答,确保保持一致。用户之前询问的是关于使用for循环遍历字符串的方法,现在转向字符串到列表的转换,但这两个问题都是关于Java字符串处理的,可能有潜在的联系。 用户提供了三个引用内容,其中引用[1]提到了使用JSON库将String转换为List<Object>,这可能对当前问题有帮助。引用[2]讨论的是字符串替换方法,可能与当前问题无关,但需要确认。引用[3]是类型不匹配的错误,可能在转换过程中出现,需要注意类型安全。 用户的需求明确:将String转换为List<String>。我需要考虑几种常见方法,并确保解决方案正确、高效,同时处理可能的异常情况。根据引用[1],使用JSON库如JSONArray是一个方法,但用户可能没有指定使用哪个库,需要提到不同的库,比如org.json或Gson、Jackson。另外,用户可能不想依赖外部库,因此需要提供纯Java方法,比如使用split()方法,或者Java 8的Stream API。 首先,split()方法是最直接的,但需要注意分隔符是否正确,以及处理空字符串的情况。例如,如果字符串是用逗号分隔的,可以用split(","),但如果有逗号前后空格,可能需要用split("\\s*,\\s*")来去除空格。同时,Arrays.asList()返回的是固定大小的列表,用户可能需要可变的列表,所以建议使用new ArrayList<>(Arrays.asList(...))。 其次,使用Java 8的Stream API可以更灵活,比如分割后过滤空值,或者处理更复杂的情况。例如,使用Pattern.splitAsStream()来处理正则表达式分割,并收集到列表中。 第三,使用第三方库如Gson或Jackson,可以处理JSON格式的字符串转换。需要给出示例代码,并说明不同库的使用方法,以及可能需要的依赖。 还要考虑用户可能的错误,比如字符串格式不正确导致解析失败,或者类型转换异常。例如,如果字符串不是有效的JSON数组,使用JSON库会抛出异常,需要提醒用户处理异常。 另外,用户提供的引用[1]中的代码使用了JSONArray.fromObject和JSONArray.toList,这可能来自旧的JSON库如json-lib,但现代项目更多使用Gson或Jackson,所以需要指出这一点,并提供对应的示例。 还要注意类型安全,特别是在使用泛型时,避免出现引用[3]中的类型不匹配错误。例如,在使用Gson时,需要正确使用TypeToken来获取泛型类型信息,确保转换后的列表类型正确。 最后,总结不同方法的优缺点,帮助用户根据具体情况选择合适的方法。比如,split()方法简单但功能有限,JSON库适合处理复杂结构,Stream API提供更多灵活性。 现在需要将这些思路整理成步骤清晰的回答,涵盖多种方法,指出注意事项,并给出示例代码,同时提醒可能出现的错误和解决方法。确保回答结构清晰,帮助用户逐步解决问题,并保证真实可靠。</think>在Java中将字符串转换为$List<String>$列表需根据数据格式和需求选择合适方法,以下是五种典型实现方式及注意事项: --- ### 一、基础分割法(简单字符串) **适用场景**:逗号/分号等固定分隔符的字符串 **实现代码**: ```java String str = "apple,banana,orange"; List<String> list = Arrays.asList(str.split(",")); // 固定大小列表 // 需要可修改列表时: List<String> mutableList = new ArrayList<>(Arrays.asList(str.split("\\s*,\\s*"))); // 带空格处理 ``` **特点**: - 使用$split()$方法配合正则表达式 - 处理带空格的场景需调整正则表达式(如$\\s*,\\s*$) --- ### 二、JSON解析法(结构化数据) **适用场景**:JSON格式字符串转换 **方案对比**: | 库名称 | 依赖配置 | 示例代码片段 | |----------|----------------------------|-----------------------------------------------------------------------------| | **Gson** | `implementation 'com.google.code.gson:gson:2.10.1'` | ```java Type listType = new TypeToken<List<String>>(){}.getType(); List<String> list = new Gson().fromJson(str, listType);``` | | **Jackson** | `implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'` | ```java ObjectMapper mapper = new ObjectMapper(); List<String> list = mapper.readValue(str, new TypeReference<>() {});``` | **注意事项**: - 必须处理$JsonSyntaxException$异常[^1] - JSON数组格式必须严格匹配(如$["a","b"]$) --- ### 三、流式处理(Java 8+) **适用场景**:需要过滤/转换操作 **示例代码**: ```java // 基础分割 List<String> list1 = Pattern.compile(",") .splitAsStream(str) .collect(Collectors.toList()); // 带数据清洗 List<String> list2 = Arrays.stream(str.split(",")) .map(String::trim) .filter(s -> !s.isEmpty()) .collect(Collectors.toList()); ``` --- ### 四、手动解析法 **适用场景**:自定义格式字符串(如混合分隔符) **实现示例**: ```java String complexStr = "apple;banana|orange"; List<String> list = new ArrayList<>(); try (Scanner scanner = new Scanner(complexStr)) { scanner.useDelimiter("[;|]"); // 正则表达式定义分隔符 while (scanner.hasNext()) { list.add(scanner.next().trim()); } } ``` --- ### 五、第三方工具库 **Apache Commons Lang3方案**: ```java // 添加依赖:implementation 'org.apache.commons:commons-lang3:3.13.0' List<String> list = new ArrayList<>(ListUtils.immutableList(str.split(","))); ``` --- ### 六、典型错误规避 1. **不可变列表问题** ```java List<String> fixedList = Arrays.asList(str.split(",")); fixedList.add("grape"); // 抛出UnsupportedOperationException ``` **解决方案**:使用$new ArrayList<>()$包裹 2. **正则表达式错误** ```java "a.b".split("."); // 返回空数组(需转义为split("\\.")) ``` 3. **JSON格式不匹配** ```java // 输入"apple,banana"会报错,正确JSON数组应为["apple","banana"] ``` --- ### 方法选择建议 | 方法 | 执行效率 | 灵活性 | 复杂度 | 推荐场景 | |---------------|----------|--------|--------|------------------------| | 基础分割法 | ★★★★ | ★★ | 低 | 简单分隔符字符串 | | JSON解析法 | ★★ | ★★★★ | 中 | 结构化数据转换 | | 流式处理 | ★★★ | ★★★★ | 中 | 需要数据清洗/转换 | | 手动解析 | ★★ | ★★★★ | 高 | 复杂自定义格式 | --- ### 扩展应用 **多层嵌套结构处理**: ```java // 处理类似"[["a","b"],["c"]]"的JSON Type nestedType = new TypeToken<List<List<String>>>(){}.getType(); List<List<String>> matrix = new Gson().fromJson(str, nestedType); ``` **性能优化技巧**: 1. 预编译正则表达式: ```java private static final Pattern SPLIT_PATTERN = Pattern.compile(","); List<String> list = SPLIT_PATTERN.splitAsStream(str).collect(Collectors.toList()); ``` 2. 避免重复创建对象(如JSON解析器) --- --相关问题--: 1. 如何处理包含特殊字符(如逗号在引号内)的CSV字符串解析? 2. Java 17中新增的`splitWithDelimiters`方法有何优势? 3. 使用Gson库时如何自定义null值的处理策略? 4. 大文本文件流式转换到List<String>的最佳实践是什么? [^1]: 需要处理`JsonSyntaxException`异常确保格式正确性 [^2]: Apache Commons Lang官方文档推荐的可变列表创建方法 [^3]: Java Pattern类文档中关于预编译正则的性能说明
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值