1 /* 2 * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.util; 27 28 import java.util.function.Consumer; 29 import java.util.function.IntFunction; 30 import java.util.stream.Stream; 31 import java.util.stream.StreamSupport; 32 import jdk.internal.util.ArraysSupport; 33 34 /** 35 * Provides a reverse-ordered view of any Deque. Not serializable. 36 */ 37 class ReverseOrderDequeView<E> implements Deque<E> { 38 final Deque<E> base; 39 ReverseOrderDequeView(Deque<E> deque)40 private ReverseOrderDequeView(Deque<E> deque) { 41 base = deque; 42 } 43 of(Deque<T> deque)44 public static <T> Deque<T> of(Deque<T> deque) { 45 if (deque instanceof ReverseOrderDequeView<T> rodv) { 46 return rodv.base; 47 } else { 48 return new ReverseOrderDequeView<>(deque); 49 } 50 } 51 52 // ========== Iterable ========== 53 forEach(Consumer<? super E> action)54 public void forEach(Consumer<? super E> action) { 55 for (E e : this) 56 action.accept(e); 57 } 58 iterator()59 public Iterator<E> iterator() { 60 return base.descendingIterator(); 61 } 62 spliterator()63 public Spliterator<E> spliterator() { 64 return Spliterators.spliterator(this, Spliterator.ORDERED); 65 } 66 67 // ========== Collection ========== 68 add(E e)69 public boolean add(E e) { 70 base.addFirst(e); 71 return true; 72 } 73 addAll(Collection<? extends E> c)74 public boolean addAll(Collection<? extends E> c) { 75 boolean modified = false; 76 for (E e : c) { 77 base.addFirst(e); 78 modified = true; 79 } 80 return modified; 81 } 82 clear()83 public void clear() { 84 base.clear(); 85 } 86 contains(Object o)87 public boolean contains(Object o) { 88 return base.contains(o); 89 } 90 containsAll(Collection<?> c)91 public boolean containsAll(Collection<?> c) { 92 return base.containsAll(c); 93 } 94 isEmpty()95 public boolean isEmpty() { 96 return base.isEmpty(); 97 } 98 parallelStream()99 public Stream<E> parallelStream() { 100 return StreamSupport.stream(spliterator(), true); 101 } 102 103 // copied from AbstractCollection remove(Object o)104 public boolean remove(Object o) { 105 Iterator<E> it = iterator(); 106 if (o==null) { 107 while (it.hasNext()) { 108 if (it.next()==null) { 109 it.remove(); 110 return true; 111 } 112 } 113 } else { 114 while (it.hasNext()) { 115 if (o.equals(it.next())) { 116 it.remove(); 117 return true; 118 } 119 } 120 } 121 return false; 122 } 123 124 // copied from AbstractCollection removeAll(Collection<?> c)125 public boolean removeAll(Collection<?> c) { 126 Objects.requireNonNull(c); 127 boolean modified = false; 128 Iterator<?> it = iterator(); 129 while (it.hasNext()) { 130 if (c.contains(it.next())) { 131 it.remove(); 132 modified = true; 133 } 134 } 135 return modified; 136 } 137 138 // copied from AbstractCollection retainAll(Collection<?> c)139 public boolean retainAll(Collection<?> c) { 140 Objects.requireNonNull(c); 141 boolean modified = false; 142 Iterator<E> it = iterator(); 143 while (it.hasNext()) { 144 if (!c.contains(it.next())) { 145 it.remove(); 146 modified = true; 147 } 148 } 149 return modified; 150 } 151 size()152 public int size() { 153 return base.size(); 154 } 155 stream()156 public Stream<E> stream() { 157 return StreamSupport.stream(spliterator(), false); 158 } 159 toArray()160 public Object[] toArray() { 161 return ArraysSupport.reverse(base.toArray()); 162 } 163 164 @SuppressWarnings("unchecked") toArray(T[] a)165 public <T> T[] toArray(T[] a) { 166 return ArraysSupport.toArrayReversed(base, a); 167 } 168 toArray(IntFunction<T[]> generator)169 public <T> T[] toArray(IntFunction<T[]> generator) { 170 return ArraysSupport.reverse(base.toArray(generator)); 171 } 172 173 // copied from AbstractCollection toString()174 public String toString() { 175 Iterator<E> it = iterator(); 176 if (! it.hasNext()) 177 return "[]"; 178 179 StringBuilder sb = new StringBuilder(); 180 sb.append('['); 181 for (;;) { 182 E e = it.next(); 183 sb.append(e == this ? "(this Collection)" : e); 184 if (! it.hasNext()) 185 return sb.append(']').toString(); 186 sb.append(',').append(' '); 187 } 188 } 189 190 // ========== Deque and Queue ========== 191 addFirst(E e)192 public void addFirst(E e) { 193 base.addLast(e); 194 } 195 addLast(E e)196 public void addLast(E e) { 197 base.addFirst(e); 198 } 199 descendingIterator()200 public Iterator<E> descendingIterator() { 201 return base.iterator(); 202 } 203 element()204 public E element() { 205 return base.getLast(); 206 } 207 getFirst()208 public E getFirst() { 209 return base.getLast(); 210 } 211 getLast()212 public E getLast() { 213 return base.getFirst(); 214 } 215 offer(E e)216 public boolean offer(E e) { 217 return base.offerFirst(e); 218 } 219 offerFirst(E e)220 public boolean offerFirst(E e) { 221 return base.offerLast(e); 222 } 223 offerLast(E e)224 public boolean offerLast(E e) { 225 return base.offerFirst(e); 226 } 227 peek()228 public E peek() { 229 return base.peekLast(); 230 } 231 peekFirst()232 public E peekFirst() { 233 return base.peekLast(); 234 } 235 peekLast()236 public E peekLast() { 237 return base.peekFirst(); 238 } 239 poll()240 public E poll() { 241 return base.pollLast(); 242 } 243 pollFirst()244 public E pollFirst() { 245 return base.pollLast(); 246 } 247 pollLast()248 public E pollLast() { 249 return base.pollFirst(); 250 } 251 pop()252 public E pop() { 253 return base.removeLast(); 254 } 255 push(E e)256 public void push(E e) { 257 base.addLast(e); 258 } 259 remove()260 public E remove() { 261 return base.removeLast(); 262 } 263 removeFirst()264 public E removeFirst() { 265 return base.removeLast(); 266 } 267 removeLast()268 public E removeLast() { 269 return base.removeFirst(); 270 } 271 removeFirstOccurrence(Object o)272 public boolean removeFirstOccurrence(Object o) { 273 return base.removeLastOccurrence(o); 274 } 275 removeLastOccurrence(Object o)276 public boolean removeLastOccurrence(Object o) { 277 return base.removeFirstOccurrence(o); 278 } 279 } 280