/**
* Removes all of the elements from this deque.
*/
public void clear() {
while (pollFirst() != null)
;
}
current implementation is just pop the elements in the queue one by one, but could that be done by just resetting the head and tail pointer term to an empty queue ?
what's need to be taken care here?
The pollFirst() method does a lot more than just pop items from the queue. It does it in a thread-safe manner.
public E pollFirst() {
for (Node<E> p = first(); p != null; p = succ(p)) {
E item = p.item;
if (item != null && p.casItem(item, null)) {
unlink(p);
return item;
}
}
return null;
}
Since you want to keep your concurrent collection concurrent, one way is to make sure you're using already concurrent operations, such as pollFirst().
It's also worth noting that clear() is "less important" as an operation compared to others, so even though it might be possible to implement it differently, doing so would be of little use.
Related
I am trying to write a C++ program to supply tree nodes to this loop:
bin_tree<int> *my_tree = ...
for (bin_tree<int>::iterator n = my_tree->begin();
n != my_tree->end(); ++n)
{
cout << *n << "\n";
}
The class I have is written in Java, and I would like to translate it into C++, however I am having trouble doing so. This is the class:
class BinTree<T> implements Iterable<T> {
BinTree<T> left;
BinTree<T> right;
T val;
// other methods: insert, delete, lookup, ...
public Iterator<T> iterator()
{
return new TreeIterator(this);
}
private class TreeIterator implements Iterator<T>
{
private Stack<BinTree<T>> s = new Stack<BinTree<T>>();
TreeIterator(BinTree<T> n)
{
if (n.val != null) s.push(n);
}
public boolean hasNext()
{
return !s.empty();
}
public T next()
{
if (!hasNext()) throw new NoSuchElementException();
BinTree<T> n = s.pop();
if (n.right != null) s.push(n.right);
if (n.left != null) s.push(n.left);
return n.val;
}
public void remove()
{
throw new UnsupportedOperationException();
}
}
}
Any help on how to write this program correctly in C++ would be appreciated, I am not sure how to properly implement the preorder iterator.
If you are trying to create a container that supports iterators I would suggest the following (you probably know all this but it may help you write good C++):
Understand iterators (in your case it may make sense to have bidirectional iterators). Iterators are wrappers to pointers in C++.
Understand the underlying data structure you want (binary tree or binary search tree?).
How should an iterator traverse a tree? (Preorder,inorde,postorder, or level order)
My approach would be to write my own node class/struct. Then write an iterator class that handles the pointer manipulation. If you need to handle allocations a certain way I would write a custom allocator to help too. Finally write your container that uses the other classes. (Modular and separates out functionality in way that is easy to understand in C++)
If you are just looking for the iterator logic and have everything else you need; begin is the first address and can be wrapped as &data [0] for example. End is the last address in similar manner. ++ operator is supported on pointers and will move along linearly towards end. Still will want to figure out moving the tree should work! May even provide multiple ways.
Good luck!
I have made my own Deque class with the following methods:
Deque#pushLeft(E e), pushRight(E e), popLeft() and popRight().
Is it possible to make a method which could change any elements of a Deque? I would like to edit them from left and from right. So editRight(index, E newElement) and the same for editLeft.
How would I start doing this? Would I need to use an Iterator?
You have implemented your Deque as a double linked list. The simplest way to support editLeft and editRight is to just step along the links until you reach the node you wish to change.
Something like:
public void editLeft(int index, Item item) {
Node node = right;
while (node != null && index > 0) {
node = node.prev;
index--;
}
if (node != null) {
node.item = item;
} else {
throw new IllegalRangeException("Attempt to edit value with illegal index");
}
}
Deque is ADT and it could be implemented by linked list or Arrays as data structures. Your answer depends upon the type of data structure being used to store elements.and also I would suggest you to implement a peek operation and it would give you a reference of an element for edit propose .peek operation could be used by other high-level operations like delete/contains etc.
Effective java greatly stresses on localizing scope of variable. But in case we have an if else it may cause multiple declations eg:
public List<E> midPoint() {
if (first == null) {
throw new NullPointerException("Linked list is empty");
}
if (first.next == null) {
ArrayList<E> arr = new ArrayList<E>();
arr.add(first.element);
return arr;
}
Node<E> fast = first.next;
Node<E> slow = first;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
// even count for number of nodes in linkedlist.
if (fast != null) {
ArrayList<E> arr = new ArrayList<E>();
arr.add(slow.element);
arr.add(slow.next.element);
return arr;
} else {
ArrayList<E> arr = new ArrayList<E>();
arr.add(slow.element);
return arr;
}
}
In the above code Arraylist defination / declaration occurs multiple times, but the variable is localized.. Is it good the way it is OR should arrayList be declared at the top and returned where its matches condition : eg:
public List<E> midPoint() {
if (first == null) {
throw new NullPointerException("Linked list is empty");
}
ArrayList<E> arr = new ArrayList<E>(); // NOTE - JUST A SINGLE DECLARATION.
if (first.next == null) {
arr.add(first.element);
return arr;
}
Node<E> fast = first.next;
Node<E> slow = first;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
// even count for number of nodes in linkedlist.
if (fast != null) {
arr.add(slow.element);
arr.add(slow.next.element);
return arr;
} else {
arr.add(slow.element);
return arr;
}
}
Thanks
In this case, it is advised that you declare it in only one place. It will be more readable and spare some lines of code.
Renaming would also be good, maybe something that suggests that is the final result of your method (like returnArray, resultArray).
In other circumstances, when that list would mean several different things, it would be really better to declare it, in that case, you would have different names too.
Should we localize scope variables at cost of multiple declarations
Different people (including well respected authors of well-known text books) will have different opinions on what makes code readable. The problem, is that readability is a subjective measure: it depends on the reader.
So I think it is up to you to decide. The chances are that you are going to be the primary reader of your code, at least to start with. So ...
Use the version that you think makes the code more readable.
If you want a second opinion, ask your co-workers.
If you have chosen to use a style guide ... be guided by what it says.
FWIW, my personal opinion is that it really depends on the context. Sometimes it is better to localize, sometimes not. A lot depends on how "far away" the declaration is from the usage, and how intuitive the meaning of the variable is. (For example, if arr was named res or result, you would not need to look at the variable declaration ... assuming you knew the signature of the current method.)
There's nothing wrong with declaring it multiple times, but you have a lot of repeated code: you can significantly improve your code by refactoring.
In your case, the JDK provides a convenience utility method to create ArrayLists in-line:
Instead of:
ArrayList<E> arr = new ArrayList<E>();
arr.add(slow.element);
arr.add(slow.next.element);
return arr;
Code this:
return Arrays.asList(slow.element, slow.next.element);
And so forth.
Note that the list returned from asList() is not modifiable. If you need a modifiable list, pass it to ArrayList's copy constructor:
return new ArrayList(Arrays.<E>asList(slow.element, slow.next.element));
I have developed a code to merge two already sorted linked lists in java.
I need help with the following:
How do I retain the value of head node of merged list without using tempNode?
Can this code be better optimized?
public static ListNode mergeSortedListIteration(ListNode nodeA, ListNode nodeB) {
ListNode mergedNode ;
ListNode tempNode ;
if (nodeA == null) {
return nodeB;
}
if (nodeB == null) {
return nodeA;
}
if ( nodeA.getValue() < nodeB.getValue())
{
mergedNode = nodeA;
nodeA = nodeA.getNext();
}
else
{
mergedNode = nodeB;
nodeB = nodeB.getNext();
}
tempNode = mergedNode;
while (nodeA != null && nodeB != null)
{
if ( nodeA.getValue() < nodeB.getValue())
{
mergedNode.setNext(nodeA);
nodeA = nodeA.getNext();
}
else
{
mergedNode.setNext(nodeB);
nodeB = nodeB.getNext();
}
mergedNode = mergedNode.getNext();
}
if (nodeA != null)
{
mergedNode.setNext(nodeA);
}
if (nodeB != null)
{
mergedNode.setNext(nodeB);
}
return tempNode;
}
1: You have to keep a record of the first node, which means you will have to store it in a variable such as tempNode.
2: No. There's not much to optimize here. The process is quite trivial.
There are a few possibilities:
1) Instead of using mergedNode to keep track of the previous node, use nodeA.getNext().getValue() and nodeB.getNext().getValue(). Your algorithm will become more complex and you will have to deal with a few edge cases, but it is possible to eliminate one of your variables.
2) Use a doubly linked-list, and then use either nodeA.getPrev().getValue() and nodeB.getPrev().getValue() instead of mergedNode. You will also have to deal with edge cases here too.
In order to deal with edge cases, you will have to guarantee that your references can not possibly be null before calling getPrev(), getNext() or getValue(), or else you will throw an exception.
Note that the above modifications sacrifice execution time slightly and (more importantly) simplicity in order to eliminate a variable. Any gains would be marginal, and developer time is far more important than shaving a microsecond or two off of your operation.
I am trying to implement a search method in a TreeSet. By using an iterator with a condtional I would like to be able to run through the set and print the object that matches the condition. However the way I am doing it at the moment is printing out the subsequent object rather than the current.
This is what I have so far:
public void getDetails() {
Iterator<Person> it = this.getPersonSet().iterator();
System.out.println("Enter First Name");
String first = in.next().toLowerCase();
System.out.println("Enter Second Name");
String last = in.next().toLowerCase();
while (it.hasNext()) {
if (it.next().getLast().toLowerCase().equals(last)) {
Person p = it.next();
System.out.println(p);
}
}
}
Any help would be great
This is what you would want to do:
while (it.hasNext()) {
Person p = it.next();
if (p.getLast().toLowerCase().equals(last)) {
System.out.println(p);
}
}
How do I refer to the current object in an iterator
For the record, the Iterator API does not allow you to do this. There is no notion of a "current" object. The Iterator.next() method gives you the next object ... and moves on.
(The ListIterator.previous() and ListIterator.next() methods are analogous. Note that in the ListIterator case, method behaviour is documented in terms of a cursor that denotes a position before / between / after elements in the sequence being iterated.)
The solution is to assign the result of calling it.next() to a temporary variable, as described by the accepted answer.
I don't know for sure why the designers didn't include the notion of a "current" object in the API, but I can think of a few reasons:
It would make a typical1 Iterator object bigger; i.e. an extra field to hold the current object.
It would mean 1 extra method for an Iterator class to implement.
The notion of a current object does not fit well with the "cursor" model documented in the ListIterator interface ... and implied by the current Iterator design.
There is the issue of the Iterator "hanging onto" the current object. In some cases that will prevent from being GC'ed.
The large majority of iterator use-cases don't require a current object.
Also, there are other ways to deal with this.
Sounds like a good call ...
1 - This and other points don't apply equally to all implementations of the Iterator API. Indeed, in some cases the implementation of current() will be simple. But that is beside the point. Unless you make the proposed current() method an optional2 method (like remove()) every iterator implementation ... and by extension, every Map and Collection class ... has to provide this functionality, and deal with the issues, one way or another.
2 - Optional methods come with their own problems.
If you need an existing implementation, you can use the ones from Google Guava or Apache Commons Collections.
The other answers are easier for your simple problem, but if you need to pass the iterator around and keep track of the last item returned by next(), these would help.
Here is an example using Guava with the OP's code (assumging Person indeed has a String toLowerCase() method):
import com.google.common.collect.PeekingIterator;
import static com.google.common.collect.Iterators.peekingIterator;
public void getDetails() {
PeekingIterator<Person> it = peekingIterator(this.getPersonSet().iterator());
System.out.println("Enter First Name");
String first = in.next().toLowerCase();
System.out.println("Enter Second Name");
String last = in.next().toLowerCase();
while (it.hasNext()) {
// note the usage of peek() instead of next()
if (it.peek().getLast().toLowerCase().equals(last)) {
Person p = it.next();
System.out.println(p);
}
}
}
Hold the reference of the object in a separate var:
Person current = it.next();
current.methodOne();
current.methodTwo();
When you're done with the current value, re-assing it the next
...
// done?
current = it.next();
In a loop looks like:
while( it.hasNext() ) {
Person current = it.next();
current.doA();
current.doB();
current.doC();
}
the next() method returns the current object, like this:
private class IterSinglyLinked implements SimpleIterator<T> {
Element curr = head; // next element to return
public boolean hasNext() {
return curr != null;
}
public T next() throws Exception {
if (curr == null) throw new Exception("no more elements");
T data = curr.data;
curr = curr.next;
return data;
}
}
If it returns the next one rather than the current one, there will be no way to reach the very first one