我正在考虑替换remove(int index)
和remove(T element)
的List方法。我在哪里获取一个列表并进行一些过滤并返回一个新列表,而不要求删除该元素。我想在功能上做到这一点,因为我不想改变原始列表。
这是我的尝试。
List<Integer> integers = Arrays.asList(2, 4, 1, 2, 5, 1);
Integer elementToRemove = 1;
List<Integer> collect =
integers.stream()
.filter(elements -> !elements.equals(elementToRemove))
.collect(Collectors.toList());
这将删除所有1。
我不会只删除第一个1
,因此我会留下像[2,4,2,5,1]
我知道如何使用indexOf()
和sublist()
以及addAll()
来完成此操作。但我觉得这不如使用溪流那么好。
寻找使用流实现remove(int index)
和remove(T element)
的功能性解决方案。
答案 0 :(得分:2)
我同意@Aominè,但这可以作为流API的替代方案
IntStream.range(0,integers.size())
.filter(i->i != integers.indexOf(elementToRemove))
.mapToObj(i->integers.get(i))
.collect(Collectors.toList());
由于@Aominè评论优化,首先找到elementToRemove
的索引,然后在过滤器中使用它。
答案 1 :(得分:1)
虽然我的另一个答案肯定是我推荐的方式,而@Hadi也提供了“流”替代方案,它也是有效的。我决定使用不同的方法来使用JDK-8的功能来实现相同的结果。
在JDK-9中有一个takeWhile和dropWhile方法,前者返回一个流,该流包含从与给定谓词匹配的流中获取的元素的最长前缀。
后者在删除与给定谓词匹配的最长元素前缀后,返回由给定流的剩余元素组成的流。
这里的想法是消耗元素而不等于elementToRemove
:
integers.stream()
.takeWhile(e -> !Objects.equals(e, elementToRemove))
并删除元素,但不等于elementToRemove
和skip(1)
以排除elementToRemove
:
integers.stream()
.dropWhile(e -> !Objects.equals(e, elementToRemove))
.skip(1)
因此产生两个流,其中第一个流是所有前面的数字到elementToRemove
,第二个流加上skip(1)
是elementToRemove
之后的所有元素然后我们只是将它们连接起来收集到列表实现。
List<Integer> result = Stream.concat(integers.stream()
.takeWhile(e -> !Objects.equals(e, elementToRemove)),
integers.stream()
.dropWhile(e -> !Objects.equals(e, elementToRemove))
.skip(1))
.collect(Collectors.toList());
假设列表中不存在要删除的元素,takeWhile
将使用所有元素,dropWhile
将删除所有元素,当我们合并这两个流时,我们返回初始元素
总的来说,这将取得与其他答案相同的结果。
但是,不要在生产代码中使用此解决方案,因为它不是最理想的,并且不明显代码的作用。它只是在这里展示完成上述要求的不同方法。