为什么我收到此错误:错误:二进制运算符"%"的操作数类型错误?



我目前正在做一个练习,只对int数组的奇数元素进行排序。程序不应该影响偶数元素,例如:

[5, 3, 8, 0, 1] --> [1, 3, 8, 0, 5]
但是,当我运行以下代码时,编译器给出以下错误:
Main.java:21: error: ')' expected
int [] res = Arrays.asList(array).stream().mapToInt((x[0]) -> x[0]%2 == 0 ? x[0] : listInt.get(++j)).collect(Collectors.toList()).toArray();
^
Main.java:21: error: not a statement
int [] res = Arrays.asList(array).stream().mapToInt((x[0]) -> x[0]%2 == 0 ? x[0] : listInt.get(++j)).collect(Collectors.toList()).toArray();
            ^
Main.java:21: error: ';' expected
int [] res = Arrays.asList(array).stream().mapToInt((x[0]) -> x[0]%2 == 0 ? x[0] : listInt.get(++j)).collect(Collectors.toList()).toArray();
                                     ^
3 errors

下面是我的代码:

public static void main(String[] args) {
int[] array = new int[]{ 5, 3, 1, 8, 0 };
int j = 0;
List<Integer> listInt = Arrays.stream(array).filter(x -> x%2 != 0).sorted().boxed().collect(Collectors.toList());
int [] res = Arrays.asList(array).stream().mapToInt(x -> x%2 == 0 ? x : listInt.get(++j)).collect(Collectors.toList()).toArray();   
}

你能帮我改正这些错误吗?

基本上你需要做3个改变:

  1. Arrays.stream(array)更改为IntStream.of(array)
  2. int j = 0;更改为int[] j = {0};
  3. ++j更改为j[0]++

第一个更改是必需的,因为Arrays.stream(array)创建了一个包含1个元素的int[]流,但是您想要一个int流,所以直接使用IntStream

第二个变化更微妙。因为lambda中的所有项都必须是有效的final-即您不能更改它们的值-++j将无法编译。通过创建jint[],您可以更改其内容而无需更改引用j

第三个变化是一个逻辑问题:++j(或新版本中的++j[0])在使用之前增加

,因此将导致最终操作的越界异常。你的代码:

int[] j = {0};
int[] odds = IntStream.of(array).filter(x -> x%2 != 0).sorted().toArray();
int [] res = IntStream.of(array).map(x -> x%2 == 0 ? x : odds[j[0]++]).toArray();

请注意,您不需要将int框为Integer,并且为了可读性,我将隐晦的listInt重命名为odds

"proper"解决方案是将j更改为AtomicInteger-类似地,引用j不会更改,但其内容可能会更改:

AtomicInteger j = new AtomicInteger();
int[] odds = IntStream.of(array).filter(x -> x%2 != 0).sorted().toArray();
int [] res = IntStream.of(array).map(x -> x%2 == 0 ? x : odds[j.getAndIncrement()]).toArray();

在您的Arrays.asList(array)语句中,您正在创建一个List,其中每个元素都是int数组,因此当您流式传输List时,流期望每个元素都是int[],而不是int。在您的示例中,流只包含array变量。当你执行x -> x % 2 == 0时,你不是将其应用于数组的元素,而是应用于数组本身;因此给出了错误。

此外,lambda表达式只允许使用final或有效final变量,即值不会改变的变量。您在流中的++j表达式也不被接受。

这是你代码的固定版本:

public class Main {
public static void main(String[] args) {
int[] array = new int[]{5, 3, 1, 8, 0};
//Passing to list returned by the stream to a PriorityQueue to store the odd numbers sorted with their natural order.
//In this way, there is no need to sort the elements within the stream and we can use the queue as an effectively final variable while still polling its elements
PriorityQueue<Integer> queue = new PriorityQueue<>(Arrays.stream(array).filter(x -> x % 2 != 0).boxed().collect(Collectors.toList()));
//Declaring and initializing the result array in order to pass it to the toArray method
Integer[] res = new Integer[0];
//For each element of the stream we return the even numbers while we pop the odd sorted numbers from the queue
res = Arrays.stream(array).boxed().map(x -> x % 2 == 0 ? x : queue.poll()).collect(Collectors.toList()).toArray(res);
//Printing the result on screen
System.out.println(Arrays.toString(res));
}
}

最新更新