Java 8 : 计算数字 4 在给定 int 数组中的出现次数

Java 8 : Count the occurrence of digit 4 in the given int array

我是 Java 8 的新手。我尝试了几种方法来使用 Streams API 来解决我们得到一个 int = {48, 44, 4, 88、84、16、12、13}。我要做的就是在整个数组中找到数字 4 的出现。我尝试了以下代码 -

int[] array = new int[] {48,44,4,88,84,16,12,13};

        List<Integer> list = new ArrayList<Integer>();
        
        for(int i:array) {
            list.add(i);
        }
        
        List<Integer> l = list.stream().filter(n->n%10)
                .map(n->n%10)
                        .collect(Collectors.toList());
        System.out.println(l);

请建议使用 Streams API 解决此问题的方法。

首先,您需要从给定的 int[] 数组中获取一个 stream。您可以使用静态方法 IntStream.of, or with Arrays utility class and it's method stream().

两者都会给你一个 IntStream - int 原语流。为了将流元素收集到 list 中,您需要将其转换为 objects 的流。为此,您可以在流管道上应用方法 boxed(),每个 int 元素将被 Integer 对象包裹。

为了在给定的列表中找到包含目标数字的所有元素 (4),可以将目标数字转成字符串,然后在其基础上套用一个filter

public static List<Integer> findOccurrencesOfDigit(List<Integer> source, 
                                                   int digit) {
    String target = String.valueOf(digit);

    return source.stream()
                    .filter(n -> String.valueOf(n).contains(target))
                    .collect(Collectors.toList());
}

main()

public static void main(String[] args) {
    int[] nums = {48,44,4,88,84,16,12,13};

    System.out.println(findOccurrencesOfDigit(nums, 4));
}

输出

[48, 44, 4, 84]

注意:方法filter()需要一个Predicate(一个由布尔条件表示的函数,它接受一个元素和returntruefalse)

您尝试创建谓词 filter(n -> n % 10) 在句法和逻辑上都是不正确的。 n % 10 不会产生布尔值,它会给出 n.

最右边的数字

如果您想使用模数 (%) 运算符来创建谓词,您必须在 循环 中将元素除以 10 直到它不会等于 0。并在每个除法天气余数等于目标数字之前检查。可以这样做:

public static boolean containsDigit(int candidate, int digit) {
    boolean flag = false;
    while (candidate != 0) {
        if (candidate % 10 == digit) {
            flag = true;
            break;
        }
        candidate /= 10; // same as candidate = candidate / 10;
    }
    return flag;
}

您可以像这样在 lambda 表达式中使用此方法(注意:这是通过将它们提取到单独的方法中来避免多行 lambda 表达式的首选方法

filter(n -> containsDigit(n, digit))

我认为一个简单的方法是将数字列表转换为字符串并计算所选数字的出现次数。

public static void main(String[] args) {
  List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15);
  for(int i = 0; i < 10; i++) {
    System.out.println("Digit: " + i + " -> Ocurrences: " + countDigit(i, numbers);
  }
}

public static long countDigit(int target, List<Integer> numbers) {
  return numbers.stream().map(Object::toString) // Convert each number to string
                .collect(Collectors.joining()) // Join all of them into single string
                .chars() // Give me a stream of its characters
                .filter(c -> c == Character.forDigit(targer, 10)) // I just want the ones that are the same as my target
                .count(); // How many of them are there?
}

这是一种方法。

  • 流式传输数组
  • 然后在 map 中,使用余数 (%) 运算符计算每个值中四的数量。
  • 然后return计数
  • 并对这些计数求和

int[] array = new int[] { 48, 44, 4, 88, 84, 16, 12, 13 };
        
int count = Arrays.stream(array).map(k-> {
    int sum = 0;
    while (k > 3) {
        sum += (k % 10 == 4) ? 1 : 0;
        k/=10;
    }
    return sum;
}).sum();

System.out.printf("There are %d fours.%n"m count);

打印

There are 5 fours.

如果您使用的是 Java 16+,则可以使用 mapMulti

  • 每次出现 4 时,只需在流中放一个 1。
  • 他们求和。
int count = Arrays.stream(array).mapMulti((i,consumer)->{
        while (i > 3) {
            if ((i%10) == 4) {
                consumer.accept(1);
            }
            i/=10;
        }}).sum();

还有第三种效率较低的方式,只是为了好玩。

  • 将值转换为字符串
  • “删除”除 4 以外的所有字符。
  • return剩余字符串的长度。
  • 对长度求和。
int count = Arrays.stream(array)
            .map(i -> Integer.valueOf(i).toString()
                        .replaceAll("[^4]", "").length())
            .sum();