Reverse method reverses elements of a queue - java

This is not a HW or assignment. This is something i'm practicing myself.
Given a queue, write a Reverse method reverses elements of a queue. MyQueue remains unchanged.
Signature:
public Queue<T> reverse(Queue<T> myQueue) {
Note: It is unknown if the Queue is made using nodes or array.
The queue has methods already implemented, that we can use:
void enqueue(T element)
T dequeue();
boolean isFull();
boolean isEmpty();
int size();

You can reverse a queue by using a stack.
Here's how in Java:
public void reverse(Queue q)
{
Stack s = new Stack(); //create a stack
//while the queue is not empty
while(!q.isEmpty())
{ //add the elements of the queue onto a stack
s.push(q.serve());
}
//while the stack is not empty
while(!s.isEmpty())
{ //add the elements in the stack back to the queue
q.append(s.pop());
}
}
The append and serve methods of the queue are to add and remove elements of that queue.
Here's an example:
A queue has elements:
1 2 3 4
When the elements get added to a stack, the number 1 will be at the bottom of the list and 4 at the top:
1 2 3 4 <- top
Now pop the stack and put the elements back in the queue:
4 3 2 1
I hope this helped.

dequeue the elements of the input queue onto a stack
pop the elements off the stack, enqueueing each into the output queue.

You can do this without any other arrays or lists, just by recursion:
public static <T> Queue<T> flip(Queue<T> q) {
Queue<T> ret = new Queue<>();
recursiveFlip(q, ret);
return ret;
}
private static <T> void recursiveFlip(Queue<T> src, Queue<T> dest) {
T buffer = src.dequeue();
if(!src.isEmpty()) {
recursiveFlip(src, dest);
}
dest.enqueue(buffer);
}
First elements will be stacked in "shallow" part of the stack, while last elements in "deeper" part, and when recursion reaches the end, the "deeper" values will be added first and "shallow" last.
But note that each one element means one step deeper into recursion, so stack overflow error will occur if the queue is too big.
Also, the original queue will not "survive" the flip.

I've used two different approaches that don't depend on your queue size. The first one uses Stack and second one - Java 8 Stream API (the fastest).
The most effective solution for reversing queue in my tests is:
private Queue<Integer> reverse(Queue<Integer> queue) {
List<Integer> collect = queue.stream()
.collect(Collectors.toList());
Collections.reverse(collect);
return new LinkedList<>(collect);
}

Related

Priority Queue ordering generates different result compared to Arrays.sort when using the same comparator [duplicate]

This question already has answers here:
The built-in iterator for java's PriorityQueue does not traverse the data structure in any particular order. Why?
(5 answers)
Closed 8 years ago.
I was trying to insert the integers in PriorityQueue, and I know that :
If no comparator is specified when a PriorityQueue is constructed, then the default
comparator for the type of data stored in the queue is used. The default comparator will order
the queue in ascending order
However, the output I am getting is not in sorted order.
Output after running the below code is : [2, 4, 8, 6]
public static void main(String args[]) {
PriorityQueue<Integer> q = new PriorityQueue<Integer>(10);
q.offer(4);
q.offer(2);
q.offer(8);
q.offer(6);
System.out.print(q);
}
Can someone please explain why ?
A PriorityQueue is what is called a binary heap. It is only ordered/sorted in the sense that the first element is the least. In other word, it only cares about what is in the front of the queue, the rest are "ordered" when needed.
The elements are only ordered as they are dequeued, i.e. removed from the queue using poll(). This is the reason why a PriorityQueue manages to have such good performance, as it is not doing any more sorting than it needs at any time.
If you want to know how heaps work in detail I recommend this MIT lecture on heaps.
When you call System.out.print() on your PriorityQueue, it will not poll() your elements from it, but call toString(). PriorityQueue doesn't implement toString(), so it's the toString() from AbstractCollection which will be called:
public String toString() {
Iterator<E> i = iterator();
if (! i.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
E e = i.next();
sb.append(e == this ? "(this Collection)" : e);
if (! i.hasNext())
return sb.append(']').toString();
sb.append(", ");
}
}
As you can see, this method only iterate the PriorityQueue. As you can see in the PriorityQueue javadoc:
The Iterator provided in method iterator() is not guaranteed to traverse the elements of the priority queue in any particular order. If you need ordered traversal, consider using Arrays.sort(pq.toArray()).
If you want to use the PriorityQueue as it is intented to be used, you have to poll() each value and print it:
while (!q.isEmpty()) {
Integer i = q.poll();
System.out.println(i);
}
Output:
2
4
6
8
That's because java.util.PriorityQueue implements a binary heap.
Unfortunately, there is no easy way to sort a PriorityQueue. If you poll() objects until the queue is empty, the elements will be in the comparator's order. That's why when I was faced with a similar problem I've implemented my own heap class that allows me to sort the elements after the fact; which I use for a top N list of a large number of elements.
(Since I made the class on the job, I don't have the right to post it here, but it's largely modeled after python's heap.py, so there's a good source of inspiration)
An unbounded priority queue is based on a priority heap
Priority Queue.Offer() method uses siftUpComparable() internally to insert items when passed without comparator
siftUpComparable compares current element with all elements at Parent Positions(int i = paramInt - 1 >>> 1;) until the Heap condition is met
siftUpComparable Algorithm in Nutshell (if implemented through array Root=index 0):
1.Add the element to the bottom level of the heap.
2.Compare the added element with its parent; if they are in the correct order, stop.
3.If not, swap the element with its parent and return to the previous step.
Java Code
private void siftUpComparable(int paramInt, E paramE)
{
Comparable localComparable = (Comparable)paramE;
while (paramInt > 0)
{
int i = paramInt - 1 >>> 1;
Object localObject = this.queue[i];
if (localComparable.compareTo(localObject) >= 0) {
break;
}
this.queue[paramInt] = localObject;
paramInt = i;
}
this.queue[paramInt] = localComparable;
}
In Your example:
q.offer(4); -> Inserts 4
Result: PQ[0]=4
q.offer(2); -> siftUpComparable compares 4 to 2 and swap positions (comparisons at Parent Locations)
Result: PQ[0]=2,PQ[1]=4
q.offer(8); -> siftUpComparable Compares 8 and 2 (since 2 is at Parent Location)
Result: PQ[2]=8
q.offer(6);: -> siftUp Compares 6 with 4 (Parent of location 3 is Location 1 according to paramInt - 1 >>> 1; logic )
Result: PQ[3]=6
Final PQ=[2, 4, 8, 6]
How java priority Queue is suppose to work?
Basically your print statement does not traverse the tree in order.

How can I obtain the number of times a number appears in a queue (Java)?

So let's say we have a queue that can store any integer inside it.
What I needed to do (for a test), was write a function that would create (and return) a new queue without leaving the original one changed.
You could change it, but at the end of the function it would have to be as it was in the beginning
Let's assume that the only methods in class Queue are:
insert/add
remove
peek
isEmpty (returns True if queue is empty)
In the new queue we would have each integer and after it the number of times it appeared in the first queue.
Aside from the initial queue I could use: Stack(s), Array(s), new Queue(s) and possibly LinkedList(s).
Writing new functions can be done as well.
The straight up solution (I guess) would be to copy the first queue in any method, and then use while(!isEmpty) and a counter for the number which would then be added to the desired queue and removed from the copied one.
I don't have this written down at the moment but I can't really think of a cleaner and more efficient method of doing this, so any help would be appreciated. Thanks.
You're probably able to come up with a better solution with some time, but this is what I did:
public static Queue<Integer> countQueue(Queue<Integer> q) {
LinkedList<Integer> valuesList = new LinkedList<>();
// since we can't iterate on the Queue
// we remove the head element
while(!q.isEmpty()) {
int x = q.remove();
valuesList.add(x);
}
LinkedList<Integer> nonRepeated = new LinkedList<>();
LinkedList<Integer> timesCount = new LinkedList<>();
while(!valuesList.isEmpty()) {
int value = valuesList.remove();
q.add(value); // get the original queue back
int index = nonRepeated.indexOf(value);
if (index == -1) {
nonRepeated.add(value);
timesCount.add(1);
} else {
timesCount.set(index, timesCount.get(index)+1);
}
}
Queue<Integer> output = new ArrayDeque<>();
while(!nonRepeated.isEmpty()) {
output.add(nonRepeated.remove());
output.add(timesCount.remove());
}
return output;
}
If you're interested on creating a method to get the Queue's size, this might be one of the simplest solutions:
public static int getQueueSize(Queue<Integer> q) {
int i=0;
Queue<Integer> backupQueue = new ArrayDeque<>();
while(!q.isEmpty()) {
i++;
backupQueue.add(q.remove());
}
while(!backupQueue.isEmpty())
q.add(backupQueue.remove());
return i;
}
Whenever using Queues, Stacks and etc., you'll need to pay attention to the data structure's paradigm, such as FIFO(First in First out) and LIFO(Last in First out), which will dictate how you should iterate on the structure.
Idea: iterate through queue and re-add the elements to it as you do. Keep a map to store the counts of each element. Then convert the map into a queue.
Something like this (untested):
public Queue<Integer> count(Queue<Integer> input) {
int size = input.size();
Map<Integer, Integer> counts = new HashMap<>();
for (int i = 0; i < size; i++) {
Integer element = input.remove(); // take from front of queue.
if (!counts.contain(element)) {
counts.put(element, 1);
} else {
counts.put(element, counts.get(element) + 1);
}
input.add(element); // now it's in the back of the queue.
}
// convert map to queue.
Queue<Integer> output = new Queue<>();
for (Integer key : counts.keySet()) {
output.add(key);
output.add(counts.get(key));
}
return output;
Note that the output won't contain the integers in the same order... But maintaining order was not part of the problem statement. If it is, you can think of other data structures to keep your counts in.

Exception with ListIterator in Java [duplicate]

Is it possible to add elements to a collection while iterating over it?
More specifically, I would like to iterate over a collection, and if an element satisfies a certain condition I want to add some other elements to the collection, and make sure that these added elements are iterated over as well. (I realise that this could lead to an unterminating loop, but I'm pretty sure it won't in my case.)
The Java Tutorial from Sun suggests this is not possible: "Note that Iterator.remove is the only safe way to modify a collection during iteration; the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress."
So if I can't do what I want to do using iterators, what do you suggest I do?
How about building a Queue with the elements you want to iterate over; when you want to add elements, enqueue them at the end of the queue, and keep removing elements until the queue is empty. This is how a breadth-first search usually works.
There are two issues here:
The first issue is, adding to an Collection after an Iterator is returned. As mentioned, there is no defined behavior when the underlying Collection is modified, as noted in the documentation for Iterator.remove:
... The behavior of an iterator is
unspecified if the underlying
collection is modified while the
iteration is in progress in any way
other than by calling this method.
The second issue is, even if an Iterator could be obtained, and then return to the same element the Iterator was at, there is no guarantee about the order of the iteratation, as noted in the Collection.iterator method documentation:
... There are no guarantees concerning the
order in which the elements are
returned (unless this collection is an
instance of some class that provides a
guarantee).
For example, let's say we have the list [1, 2, 3, 4].
Let's say 5 was added when the Iterator was at 3, and somehow, we get an Iterator that can resume the iteration from 4. However, there is no guarentee that 5 will come after 4. The iteration order may be [5, 1, 2, 3, 4] -- then the iterator will still miss the element 5.
As there is no guarantee to the behavior, one cannot assume that things will happen in a certain way.
One alternative could be to have a separate Collection to which the newly created elements can be added to, and then iterating over those elements:
Collection<String> list = Arrays.asList(new String[]{"Hello", "World!"});
Collection<String> additionalList = new ArrayList<String>();
for (String s : list) {
// Found a need to add a new element to iterate over,
// so add it to another list that will be iterated later:
additionalList.add(s);
}
for (String s : additionalList) {
// Iterate over the elements that needs to be iterated over:
System.out.println(s);
}
Edit
Elaborating on Avi's answer, it is possible to queue up the elements that we want to iterate over into a queue, and remove the elements while the queue has elements. This will allow the "iteration" over the new elements in addition to the original elements.
Let's look at how it would work.
Conceptually, if we have the following elements in the queue:
[1, 2, 3, 4]
And, when we remove 1, we decide to add 42, the queue will be as the following:
[2, 3, 4, 42]
As the queue is a FIFO (first-in, first-out) data structure, this ordering is typical. (As noted in the documentation for the Queue interface, this is not a necessity of a Queue. Take the case of PriorityQueue which orders the elements by their natural ordering, so that's not FIFO.)
The following is an example using a LinkedList (which is a Queue) in order to go through all the elements along with additional elements added during the dequeing. Similar to the example above, the element 42 is added when the element 2 is removed:
Queue<Integer> queue = new LinkedList<Integer>();
queue.add(1);
queue.add(2);
queue.add(3);
queue.add(4);
while (!queue.isEmpty()) {
Integer i = queue.remove();
if (i == 2)
queue.add(42);
System.out.println(i);
}
The result is the following:
1
2
3
4
42
As hoped, the element 42 which was added when we hit 2 appeared.
You may also want to look at some of the more specialised types, like ListIterator, NavigableSet and (if you're interested in maps) NavigableMap.
Actually it is rather easy. Just think for the optimal way.
I beleive the optimal way is:
for (int i=0; i<list.size(); i++) {
Level obj = list.get(i);
//Here execute yr code that may add / or may not add new element(s)
//...
i=list.indexOf(obj);
}
The following example works perfectly in the most logical case - when you dont need to iterate the added new elements before the iteration element. About the added elements after the iteration element - there you might want not to iterate them either. In this case you should simply add/or extend yr object with a flag that will mark them not to iterate them.
Use ListIterator as follows:
List<String> l = new ArrayList<>();
l.add("Foo");
ListIterator<String> iter = l.listIterator(l.size());
while(iter.hasPrevious()){
String prev=iter.previous();
if(true /*You condition here*/){
iter.add("Bah");
iter.add("Etc");
}
}
The key is to iterate in reverse order - then the added elements appear on the next iteration.
I know its been quite old. But thought of its of any use to anyone else. Recently I came across this similar problem where I need a queue that is modifiable during iteration. I used listIterator to implement the same much in the same lines as of what Avi suggested -> Avi's Answer. See if this would suit for your need.
ModifyWhileIterateQueue.java
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ModifyWhileIterateQueue<T> {
ListIterator<T> listIterator;
int frontIndex;
List<T> list;
public ModifyWhileIterateQueue() {
frontIndex = 0;
list = new ArrayList<T>();
listIterator = list.listIterator();
}
public boolean hasUnservicedItems () {
return frontIndex < list.size();
}
public T deQueue() {
if (frontIndex >= list.size()) {
return null;
}
return list.get(frontIndex++);
}
public void enQueue(T t) {
listIterator.add(t);
}
public List<T> getUnservicedItems() {
return list.subList(frontIndex, list.size());
}
public List<T> getAllItems() {
return list;
}
}
ModifyWhileIterateQueueTest.java
#Test
public final void testModifyWhileIterate() {
ModifyWhileIterateQueue<String> queue = new ModifyWhileIterateQueue<String>();
queue.enQueue("one");
queue.enQueue("two");
queue.enQueue("three");
for (int i=0; i< queue.getAllItems().size(); i++) {
if (i==1) {
queue.enQueue("four");
}
}
assertEquals(true, queue.hasUnservicedItems());
assertEquals ("[one, two, three, four]", ""+ queue.getUnservicedItems());
assertEquals ("[one, two, three, four]", ""+queue.getAllItems());
assertEquals("one", queue.deQueue());
}
Using iterators...no, I don't think so. You'll have to hack together something like this:
Collection< String > collection = new ArrayList< String >( Arrays.asList( "foo", "bar", "baz" ) );
int i = 0;
while ( i < collection.size() ) {
String curItem = collection.toArray( new String[ collection.size() ] )[ i ];
if ( curItem.equals( "foo" ) ) {
collection.add( "added-item-1" );
}
if ( curItem.equals( "added-item-1" ) ) {
collection.add( "added-item-2" );
}
i++;
}
System.out.println( collection );
Which yeilds:
[foo, bar, baz, added-item-1, added-item-2]
Besides the solution of using an additional list and calling addAll to insert the new items after the iteration (as e.g. the solution by user Nat), you can also use concurrent collections like the CopyOnWriteArrayList.
The "snapshot" style iterator method uses a reference to the state of the array at the point that the iterator was created. This array never changes during the lifetime of the iterator, so interference is impossible and the iterator is guaranteed not to throw ConcurrentModificationException.
With this special collection (usually used for concurrent access) it is possible to manipulate the underlying list while iterating over it. However, the iterator will not reflect the changes.
Is this better than the other solution? Probably not, I don't know the overhead introduced by the Copy-On-Write approach.
public static void main(String[] args)
{
// This array list simulates source of your candidates for processing
ArrayList<String> source = new ArrayList<String>();
// This is the list where you actually keep all unprocessed candidates
LinkedList<String> list = new LinkedList<String>();
// Here we add few elements into our simulated source of candidates
// just to have something to work with
source.add("first element");
source.add("second element");
source.add("third element");
source.add("fourth element");
source.add("The Fifth Element"); // aka Milla Jovovich
// Add first candidate for processing into our main list
list.addLast(source.get(0));
// This is just here so we don't have to have helper index variable
// to go through source elements
source.remove(0);
// We will do this until there are no more candidates for processing
while(!list.isEmpty())
{
// This is how we get next element for processing from our list
// of candidates. Here our candidate is String, in your case it
// will be whatever you work with.
String element = list.pollFirst();
// This is where we process the element, just print it out in this case
System.out.println(element);
// This is simulation of process of adding new candidates for processing
// into our list during this iteration.
if(source.size() > 0) // When simulated source of candidates dries out, we stop
{
// Here you will somehow get your new candidate for processing
// In this case we just get it from our simulation source of candidates.
String newCandidate = source.get(0);
// This is the way to add new elements to your list of candidates for processing
list.addLast(newCandidate);
// In this example we add one candidate per while loop iteration and
// zero candidates when source list dries out. In real life you may happen
// to add more than one candidate here:
// list.addLast(newCandidate2);
// list.addLast(newCandidate3);
// etc.
// This is here so we don't have to use helper index variable for iteration
// through source.
source.remove(0);
}
}
}
For examle we have two lists:
public static void main(String[] args) {
ArrayList a = new ArrayList(Arrays.asList(new String[]{"a1", "a2", "a3","a4", "a5"}));
ArrayList b = new ArrayList(Arrays.asList(new String[]{"b1", "b2", "b3","b4", "b5"}));
merge(a, b);
a.stream().map( x -> x + " ").forEach(System.out::print);
}
public static void merge(List a, List b){
for (Iterator itb = b.iterator(); itb.hasNext(); ){
for (ListIterator it = a.listIterator() ; it.hasNext() ; ){
it.next();
it.add(itb.next());
}
}
}
a1 b1 a2 b2 a3 b3 a4 b4 a5 b5
I prefer to process collections functionally rather than mutate them in place. That avoids this kind of problem altogether, as well as aliasing issues and other tricky sources of bugs.
So, I would implement it like:
List<Thing> expand(List<Thing> inputs) {
List<Thing> expanded = new ArrayList<Thing>();
for (Thing thing : inputs) {
expanded.add(thing);
if (needsSomeMoreThings(thing)) {
addMoreThingsTo(expanded);
}
}
return expanded;
}
IMHO the safer way would be to create a new collection, to iterate over your given collection, adding each element in the new collection, and adding extra elements as needed in the new collection as well, finally returning the new collection.
Given a list List<Object> which you want to iterate over, the easy-peasy way is:
while (!list.isEmpty()){
Object obj = list.get(0);
// do whatever you need to
// possibly list.add(new Object obj1);
list.remove(0);
}
So, you iterate through a list, always taking the first element and then removing it. This way you can append new elements to the list while iterating.
Forget about iterators, they don't work for adding, only for removing. My answer applies to lists only, so don't punish me for not solving the problem for collections. Stick to the basics:
List<ZeObj> myList = new ArrayList<ZeObj>();
// populate the list with whatever
........
int noItems = myList.size();
for (int i = 0; i < noItems; i++) {
ZeObj currItem = myList.get(i);
// when you want to add, simply add the new item at last and
// increment the stop condition
if (currItem.asksForMore()) {
myList.add(new ZeObj());
noItems++;
}
}
I tired ListIterator but it didn't help my case, where you have to use the list while adding to it. Here's what works for me:
Use LinkedList.
LinkedList<String> l = new LinkedList<String>();
l.addLast("A");
while(!l.isEmpty()){
String str = l.removeFirst();
if(/* Condition for adding new element*/)
l.addLast("<New Element>");
else
System.out.println(str);
}
This could give an exception or run into infinite loops. However, as you have mentioned
I'm pretty sure it won't in my case
checking corner cases in such code is your responsibility.
This is what I usually do, with collections like sets:
Set<T> adds = new HashSet<T>, dels = new HashSet<T>;
for ( T e: target )
if ( <has to be removed> ) dels.add ( e );
else if ( <has to be added> ) adds.add ( <new element> )
target.removeAll ( dels );
target.addAll ( adds );
This creates some extra-memory (the pointers for intermediate sets, but no duplicated elements happen) and extra-steps (iterating again over changes), however usually that's not a big deal and it might be better than working with an initial collection copy.
Even though we cannot add items to the same list during iteration, we can use Java 8's flatMap, to add new elements to a stream. This can be done on a condition. After this the added item can be processed.
Here is a Java example which shows how to add to the ongoing stream an object depending on a condition which is then processed with a condition:
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
intList.add(3);
intList = intList.stream().flatMap(i -> {
if (i == 2) return Stream.of(i, i * 10); // condition for adding the extra items
return Stream.of(i);
}).map(i -> i + 1)
.collect(Collectors.toList());
System.out.println(intList);
The output of the toy example is:
[2, 3, 21, 4]
In general, it's not safe, though for some collections it may be. The obvious alternative is to use some kind of for loop. But you didn't say what collection you're using, so that may or may not be possible.

Push method implementation using Stack and List ADT

How would I go about writing an implementation of push for the stack ADT using list ADT? Assuming i'm pushing to the top of stack, would I have to create a temp list and do something to add the previous head to the tail?
private someList<E> stack;
public void push(E element){
stack.add(element);
}
//another file
public someList<E> add(E newHead){
return new someList<E>(newHead, this);
}
What is important in the implementation of the stack ADT, is where you are going to add the new elements you push and where you are going to delete elements you pop. Obviously push(someElement); pop(); should leave the stack unchanged.
So we have 2 choices, adding/removing elements at the end of the list or in the front.
public void push(E element){
stack.add(element);
}
You've chosen to add/remove them at the end of the list.
I don't know what the add method has to do, however if it returns a new someList which represents a/the new stack, then the private stack field should get this newly created stack assigned!
Note that if the purpose of add is to change the current head (replace current TOS (= Top Of Stack) by this one), then you could simply write it as follow
public someList<E> add(E newHead){
pop(); // remove TOS
push(newHead); // Add newHead as the new TOS
return this.stack;
}
I've implemented the stack ADT for String's. I leave it as a simple exercise to change it to your needs (using someList instead of List and using generics).
public class Stack {
private List<String> stack = new ArrayList<String>();
public void push(String element){
stack.add(element);
}
public List<String> add(String newHead){
stack = new ArrayList<String>(stack); // you should do "stack = new someList<E>(newHead, this);"
return stack; // return the new stack
}
public String pop() {
String res = stack.get(stack.size() - 1);
stack.remove(stack.size() - 1); //
return res;
}
public void printStack() {
System.out.println("TOS (Top Of Stack)");
for(int i = stack.size() - 1; i >= 0; i--)
System.out.println(stack.get(i));
System.out.println("EOS (End Of Stack)");
}
}
// Test it
...
String a = "a", b = "b";
Stack stck = new Stack();
stck.push(a);
stck.push(b);
stck.push(b);
stck.push(a);
stck.pop();
stck.printStack();
...
This is how the stack is changing during the test case.
TOS (Top Of Stack)
a ---> b ---> b ---> a ---> b
a b b b
a b a
a
EOS (End Of Stack)
Note that in this implementation of the stack ADT we are pushing/popping elements from the stack by adding/removing elements from the list's tail (more precisely arrayList). Which is ideal for use with java's arrayList because adding an element to the tail of the list, or removing the last element, is in O(1).
Methods specifying insertion position have to copy all array elements to the right from insertion
(Source)
You will have to check if the same holds when using your own someList implementation. However, if adding an element to the tail of the list (or removing the last element) requires you to traverse the whole list (which is the case for e.g. a single linked list, hence O(n)), then adding/removing the first element should be in O(1).
In that case you should change the stack ADT's implementation so that the front of someList is now representing the TOS and the tail of the list is representing the end of the stack. Hence push/pop will then add/remove elements at the front of the list.
EDIT : You could implement a count method :
By explicitly remembering how many elements are on the stack (i.e. you have a size field that you increment for every push() and decrement for every successful pop() (i.e. for every pop() when size > 0 then decrement size).
By relying on the size() method of the ArrayList that is used to represent the stack.
Hence a possible implementation
public class Stack {
private List<String> stack = new ArrayList<String>();
...
public int count() {
return stack.size();
}
}

How to iterate PriorityBlockingQueue in order

I have a PriorityBlockingQueue<Shirts> that uses a FIFO (first in first out) comparator in addition to other custom conditions. While obeying the priority, I need to pull out only the Green shirts. I understand the objective with a Queue is that they are intended for items to be "taken off of the top". The iterator() doesn't obey the order, so I can't use that. Should I be using a different queue altogether? How can I iterate over these items.
PriorityQueue.iterator() doesn't obey the order but retrieval operations poll, remove, peek, and element access the element at the head of the queue. So, taking into consideration that PriorityBlockingQueue cannot have null elements, you can iterate the elements in order this way
PriorityBlockingQueue<Shirts> q = ...
for (Shirts shirts; (shirts = q.poll()) != null; ) {
...
}
Another way
Shirts[] a = q.toArray(new Shirts[q.size()]);
Arrays.sort(a);
now you can iterate in both direction
Taking a look at the javadoc, you should be able to use the "take" method.
public E take()
throws InterruptedException
Description copied from interface: BlockingQueue
Retrieves and removes the head of this queue, waiting if necessary until an element becomes available.
Just throw a for loop around the queue and voila! You can iterate with no problems. :)
Assuming the queue is strictly FIFO
You can then use "put" to put the item back into the queue if it is not the green shirt
public void put(E e)
Inserts the specified element into this priority queue. As the queue is unbounded, this method will never block.
This way the non-green shirts will still be in the queue in order (once the loop is finished).
The way you have it setup
Since you are using a PriorityBlockingQueue, putting the objects right back in the queue could eventually lead to the same item being pulled off the queue each time around the loop. You would need to create a new queue to put the item back into once it is checked to see if it is a green shirt.
Example code
PriorityBlockingQueue queue = new PriorityBlockingQueue();
PriorityBlockingQueue backupqueue = new PriorityBlockingQueue();
queue.put("A");
queue.put("B");
queue.put("C");
queue.put("D");
List<String> saveList = new ArrayList<String>();
int initialSize = queue.size();
for(int i = 0; i < initialSize; i++){
String element = queue.take();
if(element.equals("C")){
saveList.add(element);
} else {
backupqueue.put(element);
}
}

Categories

Resources