我有一个Queue<Integer>
声明为Queue<Integer> queue=new LinkedList();
,我需要颠倒它的元素顺序,然后将其转换为一个int数组。我写了下面的代码:
Collections.reverse((List)queue);
int[] res=queue.stream().mapToInt(Integer::intValue).toArray();
此代码有两个问题:
(List)queue
; 那么我们还有什么更优雅的方法吗?
问题的澄清:
队列是否反转并不重要。我需要一个反向元素的int数组。
答案 0 :(得分:8)
这里不需要花哨。
static int[] toReversedArray(Queue<Integer> queue) {
int i = queue.size();
int[] array = new int[i];
for (int element : queue) {
array[--i] = element;
}
return array;
}
不是一字线,但易于阅读和快速。
答案 1 :(得分:6)
首先,请不要使用原始类型(请使用菱形运算符)。划线员还不多,但您可以先转换为int[]
,然后再使用通用语言lang ArrayUtils.reverse(int[])
,例如
Queue<Integer> queue = new LinkedList<>();
// ...
int[] arr = queue.stream().mapToInt(Integer::intValue).toArray();
ArrayUtils.reverse(arr);
您还可以编写自己的int[]
反向方法,以实现流畅的界面(例如返回int[]
),然后使其成为一个衬里。喜欢,
public static int[] reverse(int[] arr) {
for (int i = 0; i < arr.length / 2; i++) {
int temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
return arr;
}
然后
int[] arr = reverse(queue.stream().mapToInt(Integer::intValue).toArray());
答案 2 :(得分:5)
Collections.reverse
仅暗示List
,它只是Collection
的一种,不能将Queue
强制转换为List
。但是您可以尝试将其强制转换为LinkedList
:
Collections.reverse((LinkedList)queue);
详细信息 :
我怀疑是否存在用于反转队列的内置API。您仍然可以按照常规方式使用Stack
来做到这一点:
Stack<Integer> stack = new Stack<>();
while (!queue.isEmpty()) {
stack.add(queue.remove());
}
while (!stack.isEmpty()) {
queue.add(stack.pop());
}
然后按照您的意愿转换为数组
int[] res = queue.stream().mapToInt(Integer::intValue).toArray();
另一方面,如果Deque
当前满足您的需求,则您也可以仅依靠LinkedList
本身,因为它也实现了Deque
。那么您当前的实现将很简单:
LinkedList<Integer> dequeue = new LinkedList<>();
Collections.reverse(dequeue);
int[] res = dequeue.stream().mapToInt(Integer::intValue).toArray();
队列是否反向并不重要。一个int数组 我需要反向元素。
其他人已经提出的另一种解决方案是将Stream
的{{1}}反转,然后将queue
转换为数组:
mapToInt
这使用了Stuart Marks in this answer建议的实用程序Queue<Integer> queue = new LinkedList<>();
int[] res = reverse(queue.stream()).mapToInt(Integer::intValue).toArray();
,这样:
reverse
答案 3 :(得分:4)
在 Java8 版本中,您可以使用 Stream API 帮助您。
这样的代码框架:
int[] reversedQueue = queue.stream()
.collect(Collector.of(() -> new ArrayDeque<Integer>(), ArrayDeque::addFirst, (a,b)->a))
.stream().mapToInt(Integer::intValue).toArray();
答案 4 :(得分:3)
最后,我找出了这一行解决方案。
Integer[] intArray = queue.stream()
.collect(LinkedList::new, LinkedList::addFirst, LinkedList::addAll)
.toArray(new Integer[queue.size()]);
int[]
版本应该喜欢
int[] intArray = queue.stream()
.collect(LinkedList<Integer>::new, LinkedList::addFirst, LinkedList::addAll)
.stream()
.mapToInt(Integer::intValue)
.toArray();
答案 5 :(得分:3)
您可以按以下方式使用LazyIterate
中的Eclipse Collections实用程序。
int[] res = LazyIterate.adapt(queue)
.collectInt(i -> i)
.toList()
.asReversed()
.toArray();
您还可以将Collectors2
类与Java流一起使用。
int[] ints = queue.stream()
.collect(Collectors2.collectInt(i -> i, IntLists.mutable::empty))
.asReversed()
.toArray();
您可以将int
的值直接流式传输到MutableIntList
中,将其反转,然后将其转换为int
数组。
int[] ints =
IntLists.mutable.ofAll(queue.stream().mapToInt(i -> i)).asReversed().toArray();
最后,您可以将int
值直接传输到MutableIntStack
中,并将其转换为int
数组。
int[] ints =
IntStacks.mutable.ofAll(queue.stream().mapToInt(i -> i)).toArray();
注意:我是Eclipse Collections的提交者。
答案 6 :(得分:2)
这是一行,但可能效率不高:
int[] res = queue.stream()
.collect(LinkedList<Integer>::new, (l, e) -> l.addFirst(e), (l1, l2) -> l1.addAll(l2))
.stream()
.mapToInt(Integer::intValue)
.toArray();
如果您想提高效率和可读性,应该继续使用现有功能。
答案 7 :(得分:1)
这是在一行代码中使用Stream
和Collections.reverse()
的另一种解决方案:
Integer[] reversedArray = queue.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(),
list -> {
Collections.reverse(list);
return list.toArray(new Integer[0]);
}
));
OR
int[] reversedArray = queue.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(),
list -> {
Collections.reverse(list);
return list.stream()
.mapToInt(Integer::intValue)
.toArray();
}
));
答案 8 :(得分:1)
这是一种创建反转数组而不反转队列的方法:
int[] i = { queue.size() };
int[] array = new int[i[0]];
queue.forEach(n -> array[--i[0]] = n);
由于无法在lambda表达式中修改局部变量,因此上述代码非常不精通。因此,i
必须是一个单元素数组,才能克服此限制。
注意:请记住,我只是出于娱乐目的而来到此解决方案的:)