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);