What I am trying to do is save a Move objects into a Vector called topMoves. There will be many Move objects which is why I create the object within the loop.
The pastPriceMap stores prices for stocks at some past time (in this case one minute ago). The currPriceMap stores price for stocks some time within the last second.
I get the following exception:
Exception in thread "Timer-0" java.util.NoSuchElementException
This is the line that is causing the problem:
amove.setInitPrice(pastPriceMap.get(iter.next()));
The code snippet is below. When I do the System.out.println statements I get the expected output:
Iterator<String> iter = sortedTopCodes.iterator();
while(iter.hasNext()){
System.out.println(currPriceMap.get(iter.next()));
System.out.println(pastPriceMap.get(iter.next()));
Move amove = new Move();
amove.setSecCode(iter.next());
amove.setPrice(currPriceMap.get(iter.next()));
amove.setInitPrice(pastPriceMap.get(iter.next()));
topMoves.add(amove);
}
return topMoves;
The Move class looks like this:
private String secCode;
private double price;
private double initPrice;
public String getSecCode() {
return secCode;
}
public void setSecCode(String secCode) {
this.secCode = secCode;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getInitPrice() {
return initPrice;
}
public void setInitPrice(double lastPrice) {
this.initPrice = lastPrice;
}
Short answer:
For each call to hasNext() there should be only one call to next()
In your code you have 5 next() with only one hasNext()
Here, read this: http://java.sun.com/javase/6/docs/api/java/util/Iterator.html
EDIT
Longer answer:
Basically an iterator is used to ... well iterate the elements of "something" tipically a collection but it could be anything ( granted that anything returns an Iterator ).
Since you may not know how many elements does that "anything" have, there must be a way to stop iterating right? ( if it was an array, you can tell by the length property, but the iterator is used to "encapsulate" the data structure used in the implementation ) Anyway.
The iterator API defines these two methods
-hasNext(): boolean
-next(): Object ( or <E> since Java 1.5 )
So the typical idiom is this:
while( iterator.hasNext() ) { // reads: while the iterator has next element
Object o = iterator.next(); // give me that element
}
What happens if the iterator has only two items?
while( iterator.hasNext() ) { // the first time will return true, so the next line will be executed.
Object o = iterator.next(); // give me that item. ( 1st element )
Object b = iterator.next(); // oops dangerous by may work ... ( 2nd element )
Object c = iterator.next(); // eeeerhhh... disaster: NoSuchElementException is thrown.
}
This is what is happening to you. You did not verify if the iterator has another element, you just retrieve it. If the iterator happens to have some elements, it may work for a while but there will be a time ( as you just saw ) when it fails.
By the way, DO NOT even think in catching NoSuchElementException. That's a runtime exception and it indicates that something in your code logic should be fixed.
See this answer to know more about the exceptions.
Here is a version using the new for loops:
for ( String secCode : secCodeList ) {
System.out.println(currPriceMap.get(secCode));
System.out.println(pastPriceMap.get(secCode));
Move amove = new Move();
amove.setSecCode(secCode);
amove.setPrice(currPriceMap.get(secCode));
amove.setInitPrice(pastPriceMap.get(secCode));
topMoves.add(amove);
}
in the older fashion :
String secCode = null;
for ( Iterator<String> it = secCodeList.iterator(); it.hasNext() ) {
secCode = it.next();
System.out.println(currPriceMap.get(secCode));
System.out.println(pastPriceMap.get(secCode));
Move amove = new Move();
amove.setSecCode(secCode);
amove.setPrice(currPriceMap.get(secCode));
amove.setInitPrice(pastPriceMap.get(secCode));
topMoves.add(amove);
}
// while there are more lines
while(scanner.hasNextLine())
{
final String line;
final String[] words;
// get the next line
line = scanner.nextLine();
// break the line up into the words (\\s+ should break it up via whitespace)
words = line.split("\\s");
if(words.length != 5)
{
throw new WhateverExceptionMakesSense(line + " must contain 5 words");
}
System.out.println(currPriceMap.get(words[0]));
System.out.println(pastPriceMap.get(words[1]));
Move amove = new Move();
amove.setSecCode(words[2]);
amove.setPrice(currPriceMap.get(words[3]));
amove.setInitPrice(pastPriceMap.get(words[4]));
topMoves.add(amove);
}
Related
I'm in this situation: if I find a specific value in a HashSet, I have to update a field, clear the set and return the field.
Here one example:
static Set<Integer> testSet = new HashSet<>();
static Integer myField = null; // the field could be already != null
public static int testClearSet()
{
for (int i = 0; i < 100; i++) { // this is just for the test
testSet.add(i);
}
for (Integer n : testSet) {
if (n == 50) {
myField = n;
testSet.clear();
return myField;
}
}
return -1;
}
I'm wondering if doing this to the set it's safe, considering the fact that later on I should reuse the set.
I'm asking this, because I knew that to make changes over a Collection while iterating, is not a "good practice", but this case I think is a little bit different.
A possible solution would be:
boolean clear = false;
for (Integer n : testSet) {
if (n == 50) {
myField = n;
clear = true;
break;
}
}
if (clear) {
testSet.clear();
return myField;
}
So, which one is the right way?
It should be safe to remove elements from a set when using an explicit iterator. Hence the following should be safe:
Iterator<Integer> iterator = testSet.iterator();
while (iterator.hasNext()) {
Integer element = iterator.next();
if (element.intValue() == 50) {
testSet.clear();
break;
}
}
A ConcurrentModificationException is only thrown if you continue iterating after changing it manually.
What you do is change it and abort iterating, so it should be 100% safe (regardless of the for-each implementation).
The real issue is, the readability of the code. A piece of code should ideally do one job, and if this job is complicated, split it up. In particular, your code has two parts, a condition and an action:
if (some condition) do some action
So:
public static int testClearSet() {
if (setConatins(50)) {
myField = 50;
testSet.clear();
return myField;
}
return -1;
}
private static boolean setConatins(int searchFor) {
for (Integer n : testSet) {
if (n == searchFor) {
return true;
}
}
return false;
}
The latter method can be replaced with a single API call, for you to figure out.
If you know that your Set changing only in one thread, so you can clean it like in first example.
Method clear() does not throw ConcurrentModificationException.
Both your code will work.
There is indeed a restriction in modifying the collection when u iterate using fail fast iterators. That means, iterating using fail fast iterator will fail if there is any modification in the collection after the iterator was created. All the default iterators that is returned by java collection classes are fail-fast iterators.
private void removeDataTest (Collection<String> c, String item) {
Iterator<String> iter = c.iterator(); //Iterator is created.
while (iter.hasNext()) {
String data = iter.next();
if (data.equals(item)) {
//c.remove(data); //Problem. Directly modifying collection after this iterator is created. In the next iteration it will throw concurrent modification exception.
iter.remove(); //This is fine. Modify collection through iterator.
//c.clear(); break; //This is also should be okay. Modifying the collection directly, but after that it is breaking out and not using the iterator.
}
}
}
In your code, u don't continue iteration after the set is modified. So should be fine.
I have LinkedList of objects and an iterator. I know that this ConcurrentModificationException is thrown when you try to modify the list while running the iterator. But in my case, I don't understand where this modification is being done.
The iterator looks like this :
private static void insertTasks(Task t) {
if(eventQueue.size() == 0) {
eventQueue.addFirst(tsk);
return;
}
int pos = 0;
while (itr.hasNext()){
//The line below throws the exception
if (t.getArrivalTime() <= itr.next().getArrivalTime() )
{
break;
}
pos++;
}
}
I am calling this insertTasks method from another method as shown below :
tsk = null;
tsk = new Task(1,"P1",1,4.0f,1.5f,0.0f,8.0f);
insertTasks(tsk);
tsk = null;
tsk = new Task(0,"P0",2,5.0f,2.5f,1.0f,10.0f);
insertTasks(tsk);
The getArrivalTime in the Task objects looks like :
public float getArrivalTime() { return arrivalTime; }
My question is, where am I doing this modification ? The while loop where I run this iterator is not doing any modification. Does it ?
Am I missing something ?
I reckon the problem is that itr is a static field in your class and that's creating the issue, as you're adding an element to eventQueue in your second call to insertTasks().
Avoid static fields... program yourself to fear them and avoid them as much as you can :). They evil, and OO unfriendly.
I have a slight algorithmic problem. I think I miss something but can't exactly figure out what.
I want to walk to a tree containing strings and get out with a unique string.
Here is a graphical example of a tree I would like to parse.
My trees would have three different types of elements :
Boolean operators (OR, NOT, AND) => BE
other operators (like the =) => QO
leaves (last elements) =>LEAF
I would like to end up with something like this :
"LEAF QO LEAF BE LEAF QO LEAF "
For now, I use a recursive method: I check the current element of the tree, and re run the method on its children depending on the type of elements I have. For each step I would populate my final string.
public class SingleTest {
static String[] booleanElements = {"or", "and", "not"};
public static void main(String[] args) throws Exception {
CommonTree tree = (CommonTree)parser.parse().getTree();
if(true){
String where = "";
printWhere(tree, where);
System.out.println(where);
}
}
/*
* Print to where tests
*/
public static boolean isBooleanElement(CommonTree t){
return Arrays.asList(booleanElements).contains(t.toString().toLowerCase());
}
public static String printWhere(CommonTree t, String where){
//---------------------
// Checking node type
//---------------------
// Boolean Element
if (isBooleanElement(t)){
// Continue parsing the tree
for ( int i = 0; i < t.getChildCount(); i++ ) {
printWhere((CommonTree)t.getChild(i), where+ "BE");
}
}
// Last element of tree (LEAF)
else if(t.getChildCount() == 0 ){
where = where + "LEAF";
}
// query operator
else{
// Continue parsing the tree
for ( int i = 0; i < t.getChildCount(); i++ ) {
printWhere((CommonTree)t.getChild(i), where + "QO");
}
}
//---------------------
return where;
}
My problem is that this code :
String where = "";
System.out.println(printWhere(tree, where));
returns "" (Which is logical due to my implementation).
So my question is, how can I get to have a non void string as final output ?
Hope this is clear enough
Thank you for your help
Please note that this class is used for test purpose only, and I know that putting static everywhere is bad practice :)
EDIT :
The problem was (as expected) due to my lack of experience with recursion.
Here is my final code :
public static String printWhere(CommonTree t, String where){
//---------------------
// Checking node type
//---------------------
// Boolean Element
if (isBooleanElement(t)){
// Continue parsing the tree
for ( int i = 0; i < t.getChildCount(); i++ ) {
where = printWhere((CommonTree)t.getChild(i), where) + "BE";
}
}
// Last element of tree (LEAF)
else if(t.getChildCount() == 0 ){
where = where + "LEAF";
}
// query operator
else{
// Continue parsing the tree
for ( int i = 0; i < t.getChildCount(); i++ ) {
where = printWhere((CommonTree)t.getChild(i), where ) + "QO";
}
}
//---------------------
return where;
}
The problem is that you method printWhere does not return anything! You're appending the value to new where string, but since Java passes parameters by value, this newly created string is thrown away when you leave the method.
Make this method return string and return where at the end of it. Then, concatenate the result of a recursive call with the string from the above level. That's how recursion works.
Ok so say I have a function that looks for a specific word in a custom LinkedList class:
public LinkedList find(String word) {
if (this.word.equals(word))
return this;
if (next==null)
return null;
if (next.find(word)==next)
return next;
return null;
}
This code works fine, however it returns the FIRST found object that matches the criteria. What if I wanted to return the LAST object found that matches the paramater? I'm having a hard time figuring this out. Keep in mind I want to use recursion.
EDIT: What would be wrong with this code:
public LinkedList findLast(String word) {
LinkedList temp=new LinkedList(word, null);
if (next==null && next.word.equals(word))
return next;
if (next==null && !next.word.equals(word))
temp=next.findLast(word);
return temp;
}
Well, think of it this way: you need to recurse right to the end of the list, and then let the return value bubble up.
So the start of your method should either be a recursive call to look further down the list, or noting that we're at the end of the list - which is equivalent to the "further" result being null.
Now when you're returning, there are three options:
You've already found a match later than the current point - so return that reference
You've not found a match (so the return value of the recursive call was null) and:
The current point's word matches - so return the current point
The current point doesn't match - so return null
Hopefully that should be enough to get you to an implementation - if not, please ask more questions. I'd rather not give a full implementation when this is presumably homework.
Store a reference to the latest one found and keep on calling itself until it returns null -- then return the latest-reference.
Note, for clarification: you're going to have to iterate through your entire linked-list (unless you have a doubly-linked-list) to achieve this -- store a reference every time you find a match (but just overwrite the same reference each time) -- then return whatever the reference holds once you reach the end of this list.
public class LinkedList {
private static int uniqueIdCounter = 0;
private final String word;
private int uniqueId;
private LinkedList next = null;
public LinkedList( String word ) {
this.word = word;
this.uniqueId = uniqueIdCounter++;
}
#Override
public String toString() {
return this.word + "(" + this.uniqueId + ")";
}
public void setNext( LinkedList next ) {
this.next = next;
}
public LinkedList find( String word ) {
return this.find( word, null );
}
public LinkedList find( String word, LinkedList result ) {
if( this.word.equals( word ) ) {
result = this;
}
if( this.next != null ) {
result = this.next.find(word, result);
}
return result;
}
public static void main(String[] args) {
LinkedList head = new LinkedList( "A");
System.out.println( "Head is: " + head );
LinkedList B = new LinkedList( "B" );
head.setNext( B );
System.out.println( "B is: " + B );
LinkedList A2 = new LinkedList( "A" );
B.setNext( A2 );
System.out.println( "A2 is: " + A2 );
LinkedList last = head.find( "A" );
System.out.println( "Last is: " + last );
}
}
And here's the output:
Head is: A(0)
B is: B(1)
A2 is: A(2)
Last is: A(2)
Every straight recursive function has two places for some useful actions: before further method call and after:
function(n){
doBefore(n);
function(n+1)
doAfter(n)
}
doBefore() is executed "on the way forward", doAfter() is executed "on the way back". Now your algorithm checks word equality on the way forward. You have to modify your algorithm so that this check is performed on the way back.
public LinkedList find(String word, LinkedList result) {
if (this.word.equals(word))
result = this;
if (next != null )
return next.find(word, result)
return result;
Two-liner:
public LinkedList find(String word, LinkedList result) {
result = this.word.equals(word) ? this : result;
return next == null ? result : next.find(word, result);
#fprime: Ya, explanation: remember the result, replace it with later result, return when at the end.
Method with one argument:
public LinkedList find(String word){
result = this.word.equals(word) ? this : null;
if(next != null)
previous = next.find(word);
return (previous != null) ? previous : result
else
return result;
Just run it backwards from the tail.
public LinkedList find(String word) {
if (this.word.equals(word))
return this;
if (prev==null)
return null;
if (prev.find(word)==prev)
return prev;
return null;
}
To start with, you initial find(String word) does not work correctly.
Your first if statement is perfect. It is you success base case.
Your second if statement is also perfect. It is your failure base case.
Your third is where you go off the rails. You have handled all (in this case both) base cases, now all that is left is the recursive case. You don't need to check anything here. next.find(word) will return the correct answer, success or fail.
For findLast(String word), I can't add much to what Jon Skeet said. About the only advice I can add it to never have the a node check its neighbor. Each node should only ever check itself. You should see plenty of this.word.equals(word) but never next.word.equals(word).
public LinkedList find(String word) {
if(this.word.equals(word)) return this;
return next==null?null:next.find(word);
}
public LinkedList rfind(String word) {
if(next != null) {
LinkedList res = next.rfind(word);
if(res != null) return res;
}
return this.word.equals(word)?this:null;
}
I would like to store tuples objects in a concurent java collection and then have an efficient, blocking query method that returns the first element matching a pattern. If no such element is available, it would block until such element is present.
For instance if I have a class:
public class Pair {
public final String first;
public final String Second;
public Pair( String first, String second ) {
this.first = first;
this.second = second;
}
}
And a collection like:
public class FunkyCollection {
public void add( Pair p ) { /* ... */ }
public Pair get( Pair p ) { /* ... */ }
}
I would like to query it like:
myFunkyCollection.get( new Pair( null, "foo" ) );
which returns the first available pair with the second field equalling "foo" or blocks until such element is added. Another query example:
myFunkyCollection.get( new Pair( null, null ) );
should return the first available pair whatever its values.
Does a solution already exists ? If it is not the case, what do you suggest to implement the get( Pair p ) method ?
Clarification: The method get( Pair p) must also remove the element. The name choice was not very smart. A better name would be take( ... ).
Here's some source code. It basically the same as what cb160 said, but having the source code might help to clear up any questions you may still have. In particular the methods on the FunkyCollection must be synchronized.
As meriton pointed out, the get method performs an O(n) scan for every blocked get every time a new object is added. It also performs an O(n) operation to remove objects. This could be improved by using a data structure similar to a linked list where you can keep an iterator to the last item checked. I haven't provided source code for this optimization, but it shouldn't be too difficult to implement if you need the extra performance.
import java.util.*;
public class BlockingQueries
{
public class Pair
{
public final String first;
public final String second;
public Pair(String first, String second)
{
this.first = first;
this.second = second;
}
}
public class FunkyCollection
{
final ArrayList<Pair> pairs = new ArrayList<Pair>();
public synchronized void add( Pair p )
{
pairs.add(p);
notifyAll();
}
public synchronized Pair get( Pair p ) throws InterruptedException
{
while (true)
{
for (Iterator<Pair> i = pairs.iterator(); i.hasNext(); )
{
Pair pair = i.next();
boolean firstOk = p.first == null || p.first.equals(pair.first);
boolean secondOk = p.second == null || p.second.equals(pair.second);
if (firstOk && secondOk)
{
i.remove();
return pair;
}
}
wait();
}
}
}
class Producer implements Runnable
{
private FunkyCollection funkyCollection;
public Producer(FunkyCollection funkyCollection)
{
this.funkyCollection = funkyCollection;
}
public void run()
{
try
{
for (int i = 0; i < 10; ++i)
{
System.out.println("Adding item " + i);
funkyCollection.add(new Pair("foo" + i, "bar" + i));
Thread.sleep(1000);
}
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
}
public void go() throws InterruptedException
{
FunkyCollection funkyCollection = new FunkyCollection();
new Thread(new Producer(funkyCollection)).start();
System.out.println("Fetching bar5.");
funkyCollection.get(new Pair(null, "bar5"));
System.out.println("Fetching foo2.");
funkyCollection.get(new Pair("foo2", null));
System.out.println("Fetching foo8, bar8");
funkyCollection.get(new Pair("foo8", "bar8"));
System.out.println("Finished.");
}
public static void main(String[] args) throws InterruptedException
{
new BlockingQueries().go();
}
}
Output:
Fetching bar5.
Adding item 0
Adding item 1
Adding item 2
Adding item 3
Adding item 4
Adding item 5
Fetching foo2.
Fetching foo8, bar8
Adding item 6
Adding item 7
Adding item 8
Finished.
Adding item 9
Note that I put everything into one source file to make it easier to run.
I know of no existing container that will provide this behavior. One problem you face is the case where no existing entry matches the query. In that case, you'll have to wait for new entries to arrive, and those new entries are supposed to arrive at the tail of the sequence. Given that you're blocking, you don't want to have to examine all the entries that precede the latest addition, because you've already inspected them and determined that they don't match. Hence, you need some way to record your current position, and be able to search forward from there whenever a new entry arrives.
This waiting is a job for a Condition. As suggested in cb160's answer, you should allocate a Condition instance inside your collection, and block on it via Condition#await(). You should also expose a companion overload to your get() method to allow timed waiting:
public Pair get(Pair p) throws InterruptedException;
public Pair get(Pair p, long time, TimeUnit unit) throws InterruptedException;
Upon each call to add(), call on Condition#signalAll() to unblock the threads waiting on unsatisfied get() queries, allowing them to scan the recent additions.
You haven't mentioned how or if items are ever removed from this container. If the container only grows, that simplifies how threads can scan its contents without worrying about contention from other threads mutating the container. Each thread can begin its query with confidence as to the minimum number of entries available to inspect. However, if you allow removal of items, there are many more challenges to confront.
In your FunkyCollection add method you could call notifyAll on the collection itself every time you add an element.
In the get method, if the underlying container (Any suitable conatiner is fine) doesn't contain the value you need, wait on the FunkyCollection. When the wait is notified, check to see if the underlying container contains the result you need. If it does, return the value, otherwise, wait again.
It appears you are looking for an implementation of Tuple Spaces. The Wikipedia article about them lists a few implementations for Java, perhaps you can use one of those. Failing that, you might find an open source implementation to imitate, or relevant research papers.