java中removeif用法,Java8 List removeIf用法技巧

我们在写业务代码时,经常需要截取字符串转成List,然后再通过一个自定义的规则去删减元素。通常使用的是String.split(",")的这种方式来切割字符串,然后再用Arrays.asList(T...)的方式创建List。然后再去处理List 里面的内容。下面介绍一下1.8 里面存在的坑。

字符串切割

通常我们会使用Arrays.asList(T...)来生成一个ArrayList。

List compIdList = Arrays.asList(compIds.split(","));

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

当然也可以借助Guava的API 来进行更强大的处理(Guava的用法不做过多介绍):

List compIdList = Splitter.on(",").trimResults().splitToList(compIds);

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

使用List.removeIf API 剔除元素

List 创建完之后,看了下开发工具提示了个removeIf()方法。看了下里面的实现,是1.8 开始提供了,于是就尝了个鲜。在Collection 接口中的实现如下:

default boolean removeIf(Predicate super E> filter) {

Objects.requireNonNull(filter);

boolean removed = false;

final Iterator each = iterator();

while (each.hasNext()) {

if (filter.test(each.next())) {

each.remove();

removed = true;

}

}

return removed;

}

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

看上面的代码也没什么问题,于是就使用了。

compIdList.removeIf(tempCompId -> {

if (判断逻辑) {

return true;

}

return false;

});

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

运行之后发现血崩了,结果如下:

java.lang.UnsupportedOperationException: null

at java.util.AbstractList.remove(AbstractList.java:161)

at java.util.AbstractList$Itr.remove(AbstractList.java:374)

at java.util.Collection.removeIf(Collection.java:415)

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

问题解决

经过再次查看代码发现,Arrays.asList(T...)的方式和Guava的方式 new 出来的类都是静态内部类。下面以Arrays.asList 为例介绍。

它的 List 实现为:java.util.Arrays.ArrayList,迭代器实现使用的是继承的 java.util.AbstractList 中的 iterator():

public void remove() {

if (lastRet < 0)

throw new IllegalStateException();

checkForComodification();

try {

AbstractList.this.remove(lastRet);

if (lastRet < cursor)

cursor--;

lastRet = -1;

expectedModCount = modCount;

} catch (IndexOutOfBoundsException e) {

throw new ConcurrentModificationException();

}

}

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

而 java.util.AbstractList 中的 remove实现如下:

public E remove(int index) {

throw new UnsupportedOperationException();

}

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

意思就是说 AbstractList 的子类只有重写了 remove(int index) 才可以使用 removeIf() 方法。而上面 2 种 List都没有重写,因此报错。

解决办法也很简单,就是再在外面包一层可变的 java.util.ArrayList 即可。

List compIdList = new ArrayList<>(Arrays.asList(compIds.split(",")));

// 或者

List compIdList = new ArrayList<>(Splitter.on(",").trimResults().splitToList());

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值