Java 反转队列<;整数>;并将其转换为int数组
我有一个Java 反转队列<;整数>;并将其转换为int数组,java,collections,queue,Java,Collections,Queue,我有一个队列声明为Queue Queue=new LinkedList(),我需要反转其中的elments顺序,然后将其转换为int数组。我写了以下代码: Collections.reverse((List)queue); int[] res=queue.stream().mapToInt(Integer::intValue).toArray(); 此代码有两个问题: explict casting(列表)队列 我想知道是否有一种单线解决方案 那么,我们有没有更优雅的方法来做到这一点 问题的
队列
声明为Queue Queue=new LinkedList()代码>,我需要反转其中的elments顺序,然后将其转换为int数组。我写了以下代码:
Collections.reverse((List)queue);
int[] res=queue.stream().mapToInt(Integer::intValue).toArray();
此代码有两个问题:
explict casting(列表)队列
李>
我想知道是否有一种单线解决方案
那么,我们有没有更优雅的方法来做到这一点
问题的澄清:
队列是否反转并不重要。我需要反转元素的整数数组。集合。反转
仅意味着列表
,这只是集合
的一种类型,不能将队列
强制转换为列表
。但您可以尝试将其强制转换为链接列表
:
Collections.reverse((LinkedList)queue);
详细信息:
Integer[] reversedArray = queue.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(),
list -> {
Collections.reverse(list);
return list.toArray(new Integer[0]);
}
));
我怀疑是否存在用于反转队列的内置API。您仍然可以使用堆栈
按照常规方法进行操作,如下所示:
Stack<Integer> stack = new Stack<>();
while (!queue.isEmpty()) {
stack.add(queue.remove());
}
while (!stack.isEmpty()) {
queue.add(stack.pop());
}
另一方面,如果a当前满足您的需求,您可以简单地依赖LinkedList
本身,因为它也实现了Deque
。那么您当前的实现将非常简单:
LinkedList<Integer> dequeue = new LinkedList<>();
Collections.reverse(dequeue);
int[] res = dequeue.stream().mapToInt(Integer::intValue).toArray();
这将使用Stuart Marks建议的实用工具反向
,以便:
@SuppressWarnings("unchecked")
static <T> Stream<T> reverse(Stream<T> input) {
Object[] temp = input.toArray();
return (Stream<T>) IntStream.range(0, temp.length)
.mapToObj(i -> temp[temp.length - i - 1]);
}
@SuppressWarnings(“未选中”)
静态流反向(流输入){
Object[]temp=input.toArray();
返回(流)IntStream.range(0,温度长度)
.mapToObj(i->temp[temp.length-i-1]);
}
首先,请不要使用原始类型(使用菱形运算符)。虽然不是一行程序,但您可以先将其转换为int[]
,然后使用类似于commons的lang
然后
int[] arr = reverse(queue.stream().mapToInt(Integer::intValue).toArray());
最后,我找出了这一行解决方案
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();
int[]intArray=queue.stream()
.collect(LinkedList::new,LinkedList::addFirst,LinkedList::addAll)
.stream()
.mapToInt(整数::intValue)
.toArray();
这是一行,但可能效率不高:
int[] res = queue.stream()
.collect(LinkedList<Integer>::new, (l, e) -> l.addFirst(e), (l1, l2) -> l1.addAll(l2))
.stream()
.mapToInt(Integer::intValue)
.toArray();
int[]res=queue.stream()
.collect(LinkedList::new,(l,e)->l.addFirst(e),(l1,l2)->l1.addAll(l2))
.stream()
.mapToInt(整数::intValue)
.toArray();
如果你想变得高效和可读,你应该继续使用你现在拥有的。在Java8版本中,你可以使用流API来帮助你
代码的框架如下所示:
int[] reversedQueue = queue.stream()
.collect(Collector.of(() -> new ArrayDeque<Integer>(), ArrayDeque::addFirst, (a,b)->a))
.stream().mapToInt(Integer::intValue).toArray();
int[]reversedQueue=queue.stream()
.collect(Collector.of(()->new ArrayDeque(),ArrayDeque::addFirst,(a,b)->a))
.stream().mapToInt(Integer::intValue).toArray();
您可以从以下位置使用该实用程序
int[] res = LazyIterate.adapt(queue)
.collectInt(i -> i)
.toList()
.asReversed()
.toArray();
您还可以将该类与Java流一起使用
int[] ints = queue.stream()
.collect(Collectors2.collectInt(i -> i, IntLists.mutable::empty))
.asReversed()
.toArray();
您可以将int
值直接流式传输到数组中,将其反转,然后将其转换为int
数组
int[] ints =
IntLists.mutable.ofAll(queue.stream().mapToInt(i -> i)).asReversed().toArray();
int[] ints =
IntStacks.mutable.ofAll(queue.stream().mapToInt(i -> i)).toArray();
最后,您可以将int
值直接流式传输到数组中,并将其转换为int
数组
int[] ints =
IntLists.mutable.ofAll(queue.stream().mapToInt(i -> i)).asReversed().toArray();
int[] ints =
IntStacks.mutable.ofAll(queue.stream().mapToInt(i -> i)).toArray();
注意:我是Eclipse集合的提交者。这里不需要特别注意
static int[] toReversedArray(Queue<Integer> queue) {
int i = queue.size();
int[] array = new int[i];
for (int element : queue) {
array[--i] = element;
}
return array;
}
static int[]toReversedArray(队列){
int i=queue.size();
int[]数组=新的int[i];
for(int元素:队列){
数组[--i]=元素;
}
返回数组;
}
不是一行代码,但易于阅读和快速。这里有一个不同的解决方案,使用流
和集合。在一行代码中使用reverse()
:
Integer[] reversedArray = queue.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(),
list -> {
Collections.reverse(list);
return list.toArray(new Integer[0]);
}
));
或
int[] reversedArray = queue.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(),
list -> {
Collections.reverse(list);
return list.stream()
.mapToInt(Integer::intValue)
.toArray();
}
));
以下是一种在不反转队列的情况下创建反转数组的方法:
int[] i = { queue.size() };
int[] array = new int[i[0]];
queue.forEach(n -> array[--i[0]] = n);
由于无法从lambda表达式中修改局部变量,上述代码非常粗糙。所以这里i
需要是一个单元素数组,以克服这个限制
注意:请记住,我使用此解决方案只是为了好玩:)但这并不会反转队列。@nullpointer True。但是,如果目标是反转的int[]
,则不清楚队列是否也必须反转。事实上,我假设队列超出范围,并且int[]
返回给调用者。您可能不应该使用堆栈
类,因为它扩展了向量
,因此是同步的,如果使用Deque
,则将Deque.degendingIterator()
与Spliterators
和StreamSupport
结合使用可能会更有效,前提是只需要反向数组,而不需要反向Deque
。但是,代码将更加冗长。@Slaw这是肯定的。只是我写答案的目的是确保原始存储被反转,但后来OP澄清了反转的输出最终才是重要的。@Marcono1234实际上,JVM在Vector
类中删除了synchronized
块,这是它的最新版本,当它检测到它们没有共享并且它们的获取成本可以忽略不计:)但是,是的,原则上你不应该这样做,因为Vector
不建议再使用了。这不会反转队列(或其值)它看起来像您的组合器((a,b)->a
)中缺少b
result@Marcono1234没有问题。Collector.of
方法的第三个参数是一个BinaryOperator
,它是新收集器的组合器函数。在我们的代码中只有一个收集器,因此不能错过收集器中的任何元素。在这种情况下,这可能无关紧要(如果我理解正确的话)合并器只用于并行流。但是,您可能应该指出实现不正确,以防止将来有人将此代码用于并行流时出现错误
int[] i = { queue.size() };
int[] array = new int[i[0]];
queue.forEach(n -> array[--i[0]] = n);