从以特定数字开头的列表中删除数字

Remove numbers from a list that begins with a specif digit

例如,我有这个列表

List<Integer> list = new ArrayList<>();

        list.add(64);
        list.add(5);
        list.add(10);
        list.add(66);
        list.add(7);
        list.add(68);

我如何只删除以“6”开头的数字

比如你要删除6开头的数字 您可以在遍历列表时将每个 int 转换为列表,并检查字符串的第一个字符是否为“6”。如果是 6,则从列表中删除该数字

    for(int i: list)
    {
    String s= Integer.toString(i);
    if(s.charAt(0)=='6')
    {
    list.remove(new Integer(i));
    }
    }

列表结果 = list.stream().filter(a -> !a.toString().startsWith("6")).collect(Collectors.toList());

result.forEach(System.out::println);

有几种方法可以完成此任务:

  • 使用 Iterator;
  • 利用so-called 传统的for循环;
  • 借助 Stream IPA;
  • 使用方法 Collection.removeIf()

注意 尝试使用增强的 for 循环(有时称为“for-each”循环)解决此问题将导致到 CuncurrentModdificationException 在运行时(如果 collection 将被修改)。因为在 collectionenhanced for loop 的底层迭代使用了 iterator这是由 collection 提供的。并且当迭代发生时 collection 必须 not 除了通过迭代器本身,即通过使用方法 remove() 迭代器.

要使用 迭代器 遍历 collection,首先您必须通过在 .iterator() 上调用 Iterator 的一个实例=133=]。 Iterator class hasNext()next() 方法分别用于检查下一个元素是否存在和移动到下一个元素。

public static List<Integer> removeNumberIfStarsWith(List<Integer> source, int target) {
    List<Integer> copy = new ArrayList<>(source); // defencive copy to preserve the source list intact

    Iterator<Integer> iterator = copy.iterator();
    while (iterator.hasNext()) {
        Integer item = iterator.next();
        if (item.toString().startsWith(String.valueOf(target))) {
            iterator.remove();
        }
    }
    return copy;
}

要使用传统的 for 循环 实现此任务,我们必须牢记元素的删除不得弄乱尚未访问的索引。可能最简单的方法是从最后一个索引开始以相反的顺序迭代。

注:

  • 两种 风格的remove() 方法可用于List 接口的实例。一个接受 int index 另一个 object 必须删除。这个案例很有趣,因为它是 remove(int)remove(Integer) 之间的选择。请记住,当调用重载方法时,如果存在具有 相同参数类型集 (相同顺序的相同类型)的此方法的版本,编译器会将此版本映射到那个版本方法调用。 IE。方法 remove(int) 将被调用,因为我们正在传递原始类型 int.

此任务的传统 for 循环代码可能如下所示:

public static List<Integer> removeNumberIfStarsWith(List<Integer> source, int target) {
    List<Integer> copy = new ArrayList<>(source); // defencive copy to preserve the source list intact

    for (int i = copy.size() - 1; i >= 0; i--) {
        Integer item = copy.get(i);
        if (item.toString().startsWith(String.valueOf(target))) {
            copy.remove(i);
        }
    }
    return copy;
}

因为这个问题与 collections 的基本操作有关,我不假设 lambda 表达式streams[=110] 的知识=].但为了完整性和 未来的读者 ,我将提供上面提到的另外两个选项。

for information on lambda expressions and functional interfaces read this

to get familiar with Stream IPA take a look at this tutorial

流管道中方法 filter() 中的条件和 Collection.removeIf() must defenetelly look familiar to you. Both method expect Predicate 接受 object 和 returns 布尔值的函数。如果谓词 returns trueCollection.removeIf() 将删除该元素,但如果谓词 returns truefilter() 则相反,它将保留该元素].

所以 stream-based 实现可能如下所示:

public static List<Integer> removeNumberIfStarsWith(List<Integer> source, int target) {
    return source.stream()
            .filter(item -> !item.toString().startsWith(String.valueOf(target)))
            .collect(Collectors.toList());
}

Collection.removeIf()的解决方案:

public static List<Integer> removeNumberIfStarsWith(List<Integer> source, int target) {
    List<Integer> copy = new ArrayList<>(source); // defencive copy to preserve the source list intact

    copy.removeIf(item -> item.toString().startsWith(String.valueOf(target)));
    return copy;
}

main()

public static void main(String[] args) {
    List<Integer> list = List.of(64, 5, 10, 66, 7, 68);

    System.out.println(list);
    System.out.println(removeNumberIfStarsWith(list, 6)); // value 6 provided as an argument and not hardcoded inside the methods
}

输出(所有版本)

[64, 5, 10, 66, 7, 68]
[5, 10, 7]