我目前正在做一个练习,只对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个改变:
- 将
Arrays.stream(array)
更改为IntStream.of(array)
- 将
int j = 0;
更改为int[] j = {0};
- 将
++j
更改为j[0]++
第一个更改是必需的,因为Arrays.stream(array)
创建了一个包含1个元素的int[]
流,但是您想要一个int
流,所以直接使用IntStream
。
第二个变化更微妙。因为lambda中的所有项都必须是有效的final-即您不能更改它们的值-++j
将无法编译。通过创建j
和int[]
,您可以更改其内容而无需更改引用到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));
}
}