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



我是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解决此问题的方法。

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

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中,使用余数(%(运算符计算每个值中的四个数
  • 然后返回计数
  • 并将这些计数相加

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以外的所有字符
  • 返回剩余字符串的长度
  • 求和长度
int count = Arrays.stream(array)
.map(i -> Integer.valueOf(i).toString()
.replaceAll("[^4]", "").length())
.sum();

首先,您需要从给定的int[]数组中获得。您可以使用静态方法IntStream.of,也可以使用Arrays实用程序类及其方法stream()

两者都将为您提供一个IntStream-一个int基元流。为了将流元素收集到列表中,您需要将其转换为对象的流。为此,您可以在流管道上应用方法boxed(),并且每个int元素都将被Integer对象包裹。

为了在给定的列表中查找包含目标数字(4(的所有元素,您可以将目的数字

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(一个由布尔条件表示的函数,它接受一个元素并返回falsetrue(

您创建谓词filter(n -> n % 10)的尝试在语法和逻辑上都是错误的。n % 10不产生布尔值,它将给出n的最右边数字。

如果要使用modulus(%(运算符创建谓词,则必须在循环中将元素除以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))

最新更新