Solved

HashTable

Posted on 2007-04-02
10
759 Views
Last Modified: 2013-12-29
I am finding Null value in my Hashtable.
Why?

A thread keeps running infinetly as show
import java.util.*;
public class RetriveWeatherData extends Thread{
      int sleepTime = 15*60;
      String weather;
      
      public void run()
      {
            int i=0;
            String s;
            TestWeather tw=new TestWeather();      
            try {
            while (true)
            {      
                  weather=tw.fillLocalWeather(tw.cities[i],tw.country[i]);
                  /*tw.hash.put(tw.cities[i],weather);
                  System.out.println("Thread ---->"+tw.cities[i]+","+tw.country[i]+"\n");
                  System.out.println("From Hash-->"+(String)tw.hash.get(tw.cities[i]));*/
                  i++;
                  
                        if(i>=98){ Thread.sleep(100000);i=0;}
                        Thread.sleep(sleepTime);                
                     //   Enumeration e=hash.elements();
                          /* while(e.hasMoreElements())
                          {
                            System.out.println("e-->"+e.nextElement());
                          }*/                    
          
            
            
            
            //String s1;
                        if(i>=2)
                        {
            s=(String) tw.hash.get("Bangkok");
            /*s1=(String) hash.get("Bangalore");
            s=(String) hash.get("Bangkok");
          s1=(String) hash.get("Bangalore");
          System.out.println("s-->"+s+"\n"+"s1-->"+s1);*/
            System.out.println("s-->"+s);
            }
            }
            } catch (InterruptedException e) {
                   e.printStackTrace();
                }
}
      
      public static void main(String args[])
      {
            RetriveWeatherData rw=new RetriveWeatherData();
            rw.start();
      }
}


Now i will run TestWeather class (java TestWeather)

public static void main(String[] args) {
            //System.out.println("Inside Weather main()..........");
            TestWeather weatherInfo = new TestWeather();
                                        String s=weatherInfo.getFromHashTable("Bangkok");
            System.out.println("From Hash in Mainmenu()"+s);
      }

public String getFromHashTable(String City){
              System.out.println("In hashtable methhod");
              String WeatherInfo=null;
              WeatherInfo=(String)hash.get("Bangkok");
              return WeatherInfo;
             
        }


I get Null values when i run TestWeather.java but i get results when i run Thread Class.
I am running Thread Class first after some time i am running testWeather 'coz i am giving some time to fill hashtable

weather=tw.fillLocalWeather(tw.cities[i],tw.country[i]);-->gets weather info from the web(weather.com

anyone let me know why my hash values are null when i am running TestWeather.java
Result from TestWeather.java              
In hashtable methhod
From Hash in Mainmenu()nulla

0
Comment
Question by:cutie_smily
  • 5
  • 4
10 Comments
 
LVL 10

Expert Comment

by:ADSLMark
ID: 18838871
Ok, your code looks very messy and it doesnt run on my machine *at all*, so I tried to make some example code for you. I think you are taking a wrong approach to what you want to achieve, but compare your version with this, it should work similar:

//RetrieveWeatherData.java
import java.util.*;

public class RetrieveWeatherData
    extends Thread
{
    private final static int SLEEPTIME = 100000; //100 seconds

    private HashMap<String,String> data;
    private String[][] places;

    public RetrieveWeatherData()
    {
        this.data = new HashMap<String,String>();
        this.places = new String[][]{{"Vienna", "Austria"}
                                    ,{"London", "United Kingdom"}
                                    ,{"Paris" , "France"}};
    }

    public void run()
    {
        System.out.println("Started downloading weather...");
        try
        {
            while(true)
            {
                for(String[] place : places)
                {
                    String weather = downloadLocalWeather(place[0], place[1]);
                    data.put(place[0], weather);
                    System.out.println(place[0]+" ("+place[1]+") downloaded!");
                }

                Thread.sleep(SLEEPTIME);
            }
        }
        catch(InterruptedException ie)
        {
            ie.printStackTrace();
        }
    }

    public synchronized String downloadLocalWeather(String city, String country)
    {
        //This method should download the weather.
        return "It's quite sunny in "+city+" ("+country+")";
    }

    public synchronized String getWeather(String city)
    {
        return data.get(city);
    }
}

//TestWeather.java
import java.io.*;

public class TestWeather
{
    public static void main(String[] args)
    {
        RetrieveWeatherData weatherThread = new RetrieveWeatherData();
        weatherThread.start();

        try { System.in.read(); } catch(IOException ioe) { System.err.println(ioe); }
        System.out.println(weatherThread.getWeather("Paris"));
    }
}


Good luck,
Mark

PS: I think that your version doesn't perform that well because it hasn't downloaded the data yet, or some mismatch in name uses might be the cause. It's hard to tell without being able to compile your stuff.
0
 
LVL 30

Expert Comment

by:mayankeagle
ID: 18839039
>> I get Null values when i run TestWeather.java but i get results when i run Thread Class.
>> I am running Thread Class first after some time i am running testWeather 'coz i am giving some time to fill hashtable

They are running in 2 different VM instances if you use:

java RetriveWeatherData
java TestWeather

- that will never get you the output you want because they are in different process-spaces....
0
 

Author Comment

by:cutie_smily
ID: 18839671
Thread is storing all results in hashtable. Now from TestWeather.java i want to retrieve from hashtable. That's where i am getting null values. and why

public class TestWeather
{
    public static void main(String[] args)
    {
        RetrieveWeatherData weatherThread = new RetrieveWeatherData();
        weatherThread.start();

        try { System.in.read(); } catch(IOException ioe) { System.err.println(ioe); }
        System.out.println(weatherThread.getWeather("Paris"));
/*****************I want to change to******************************************?
System.out.println("Weather from hashtable"+(String)weatherThread.hash.get("Paris")); --recieving null value but

    }
}

0
 
LVL 10

Expert Comment

by:ADSLMark
ID: 18839702
Could you post your code (which will compile when copied to files)?
0
 

Author Comment

by:cutie_smily
ID: 18840716
Thread is filling hastable then why are the results null when we access hashtable from TestWeather class??

TestWeather. java has method which retrieves from website. Thread should start and should start grabbing where this thread uses TestWeather class method to grab. and has seen above its filling hashtable.

But why are results null when i am trying to access hash from Testweather class.

Its a long code..its hard to paste. and also the reason i want to use hash table is for caching purpose.

Here is the flow...start webserver-->which in turn starts thread--> which will start filling hashtable.
Now I want to access weather details for a city like Bangkok . I just want to get from hashtable.Which is faster because its already in hashtable.

Hope i will have some answers.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 10

Expert Comment

by:ADSLMark
ID: 18841659
You will have to wait for the thread to put the weather details in the hashtable. As soon as this is done it should be possible to retrieve the data from another thread with just the hashkey. Notice that this hashkey is case sensitive, so Bangkok != bangkok.
That's basically the idea, if you get null-values, then you did something wrong.

Mark
0
 

Author Comment

by:cutie_smily
ID: 18842749
I have 108 cities in my String of Cities and same for Countries.
Should i wait until Thread finishes 108 cities?

What will Another Thread do here?? Its not clear to me of having another thread and retrieve.

From JSP i am sending only cityname. It should look in Hashtable and get value.
Hashtable should have values 'coz thread would have started already.
How do you make a request from JSP..  from JSP I am using Weather=(String)hash.get(cityname);
That's also null...

From my log i can see thread is started and got the values and placng in hash. but when i access hash iam getting null..

Can you explain your ideas .?


0
 
LVL 10

Expert Comment

by:ADSLMark
ID: 18842794
I gave all the possible reasons, why you are receiving a null value. I can only help you further if I can see your code.

Some advice:
* when you add something to a hashmap, it might be a good idea to first convert the key to lowercase, whenever you request a value from the hashmap you can convert the key to lowercase aswell and there won't be any mismatches due to case sensitivity.
* when using threads make sure you keep things synchronized correctly. Only one thread should be able to access the hashmap at a given time. Also, if someone *wants* a certain value from a hashmap and it has nothing better todo then wait for this value, then you should make this thread wait() and when the value is added by another thread, this other thread should notify() that he just updated the list and it might be possible that your value is available now.

So, that's basically it, if you can't figure out why you are getting null-values, then please give us something to look at, maybe you made a mistake which you didn't see.

Mark
0
 

Author Comment

by:cutie_smily
ID: 18846220
We decided to cache only for one city. Instead using Hashtable i Just wanted to use String like shown below. Please let me know where i am going wrong

public class TestWeather {
 
        public synchronized String fillWeather(String city, String country)
            {
                  System.out.println("In fillWeather--->-->"+city);
                   Hashtable hash1=new Hashtable();
            /*      if (rd != null)
                        if (!rd.isAlive()) {
                              System.out.println("The thread is not alive so starting the thread");
                              rd = new RetriveWeatherData();
                              rd.start();
                        }*/
              String url = "/search/search?lswe=" + city +
          "," + country + "&lswa=WeatherLocalUndeclared&where=" + city +
          "," + country + "&what=WeatherLocalUndeclared";      
     
     
      String urlResult = getIntlWeatherInfo("www.weather.com", 80, url);
                  
                  //String url="http://www.wunderground.com/global/stations/45007.html";
                 //String urlResult = getIntlWeatherInfo(url);
              System.out.println("1...Url Result");
              String weatherDataStr = "";
              final String VALID_RESULT = "Right Now for";
              if (urlResult.indexOf(VALID_RESULT, 0) != -1)
                         {      
              weatherDataStr = urlResult.substring(urlResult.indexOf(VALID_RESULT, 0));
              String tokenStr = "";
              int numElements = 0;
              Vector v = new Vector();
              //gets source from the page
              StringTokenizer stk = new StringTokenizer(weatherDataStr, "\r\n\t");
              while(stk.hasMoreTokens())
              {
                    tokenStr = stripWhiteSpace(new String(stk.nextToken()));      
                  if (tokenStr.equals(""))
                  {
                      continue;
                  }
                  v.add(tokenStr);
                  numElements++;
                  if(numElements == 84)
                  {
                      break;
                  }
              }
            //  System.out.println("Iam out of while loop in getCurrentIntlWeather()-String token whiile");            
              localweather = getIntlWeatherFromVector(v);
              setlocalweather(localweather);
            // System.out.println("In filweather()-->"+localweather);
           /* hash1.put(city,displayText);
                  System.out.println("Thread ---->"+city+","+country+"\n");
                  System.out.println("From Hash-->"+(String)hash1.get(city));*/
                  
            
              }//end of if
              
                            return localweather;
            }

public static void main(String[] args) {

                      RetriveWeatherData rd=new RetriveWeatherData();
         // String s=weatherInfo.getFromHashTable("Bangkok");
        System.out.println("From Hash in Mainmenu()"+rd.getlocalweather());

                                                       }
}//end of TestWeather

----------------------------------------------------------------------------------------------------------------------
Thread Class
-----------------------------------------------------------------------------------------------------------------------

public class RetriveWeatherData extends Thread{
      int sleepTime = 15*60*100;
      String weather;
        public static Hashtable hash;
      
      String[] cities=new String[97];
      String[] country=new String[97];
      public static String localweather;
      
        public void setlocalweather(String localweather) {
            this.localweather= localweather;
        }
      
       public String getlocalweather() {
            return this.localweather;
        }
      
      RetriveWeatherData(){
          cities[0]= "Hong%20Kong";
            country[0]= "China";
      }
 
      public void run()
      {
            int i=0;
            String s;
            TestWeather tw=new TestWeather();      
            try {
            while (i<2)
            {      
                  localweather=tw.fillWeather(cities[0],country[0]);
                  setlocalweather(localweather);
                  
            }      
            
}catch(Exception e){}
            }
      
      public static void main(String args[]) throws InterruptedException
      {
            RetriveWeatherData rw=new RetriveWeatherData();
            rw.start();
            
      }
}
-----------------------------------------------------------------------------------------------------------------------
JSP page

RetriveWeatherData rw=new RetriveWeatherData();
str=rw.getlocalweather();

str is null value
---------------------------------------------------------------------------------------------------------------------------

Note: fillWeather(String city, String country) is just used by Thread class. no where else is thread method is called.

Hope this will help to figure out why null values
Made sure Thread is running i can see weather info in log


0
 
LVL 10

Accepted Solution

by:
ADSLMark earned 500 total points
ID: 18847141
Ok, here it comes, I've reimplemented some sort of weather collector. I looked at your code and it doesn't look very good (sorry!), so here is some improved code for you to work with. First an example file, so that you can actually see it really works:

//Example.java
import java.util.*;

public class Example
    extends Thread
{
    private WeatherCollector wc;

    //Construct example
    public Example(WeatherCollector wc)
    {
        this.wc = wc;
    }

    //Wait for user
    public void run()
    {
        Scanner sc = new Scanner(System.in);
        while(true)
        {
            String code = sc.next();
            if("exit".equals(code))
            {
                this.wc.close();
                break;
            }
            else if("available".equals(code))
            {
                System.out.println("Available city codes:");
                for(String cityCode : this.wc.getAvailableCityCodes())
                    System.out.println("\t"+cityCode);
            }
            else
            {
                System.out.println(this.wc.getLocalWeather(code));
            }
        }
    }

    //Program entry
    public static void main(String[] args)
    {
        //Start weather collector
        WeatherCollector wc = new WeatherCollector();
        wc.start();

        //Read city codes from user for which he wants to have the weather
        new Example(wc).start();
    }
}

//WeatherCollector.java
import java.util.*;

public class WeatherCollector
    extends Thread
{
    private final int SLEEPTIME = 1000*5; //5 seconds

    private Hashtable<String,String> lookupTable;
    private LinkedList<String> cityCodes;
    private LinkedList<WeatherRetriever> running;

    //Constructs a weather retriever
    public WeatherCollector()
    {
        this.lookupTable = new Hashtable<String,String>();

        this.running = new LinkedList<WeatherRetriever>();

        this.cityCodes = new LinkedList<String>();
        this.cityCodes.add("CHXX0049");
    }

    //Sets the weather for a specific city
    public synchronized void setLocalWeather(String cityCode, String weather)
    {
        this.lookupTable.put(cityCode.toLowerCase(), weather);
    }

    //Returns the weather from the table for a specific city
    public synchronized String getLocalWeather(String cityCode)
    {
        String weather = this.lookupTable.get(cityCode.toLowerCase());
        if(weather == null)
        {
            if(!this.cityCodes.contains(cityCode))
            {
                this.cityCodes.add(cityCode);
                return "Weather for "+cityCode+" is requested. Try again later.";
            }
            return "Not available yet";
        }
        return weather;
    }

    //Start all threads for getting the weather after each other, without waiting for the previous
    //to finish
    public void run()
    {
        while(true)
        {
            //Start all threads for retrieving the weather
            for(String cityCode : this.cityCodes)
            {
                WeatherRetriever wr = new WeatherRetriever(this, cityCode);
                wr.start();
            }

            //Wait some time before refreshing
            try { Thread.sleep(SLEEPTIME); } catch(InterruptedException ie) { System.err.println(ie); break; }
        }
    }

    //Returns all available city codes
    public synchronized LinkedList<String> getAvailableCityCodes()
    {
        return this.cityCodes;
    }

    //Removes a city code
    public synchronized void removeCityCode(String cityCode)
    {
        this.cityCodes.remove(cityCode);
    }

    //Add retriever
    public synchronized void add(WeatherRetriever wr)
    {
        this.running.add(wr);
    }

    //Remove retriever
    public synchronized void remove(WeatherRetriever wr)
    {
        this.running.remove(wr);
    }

    //Close collector
    public synchronized void close()
    {
        for(WeatherRetriever wr : this.running)
            wr.interrupt();

        this.interrupt();
    }

    //Program entry, start collector
    public static void main(String args[])
    {
        new WeatherCollector().start();
    }
}

//WeatherRetriever.java
import java.io.*;
import java.net.*;
import java.util.*;

public class WeatherRetriever
    extends Thread
{
    private WeatherCollector wc;
    private String cityCode;

    //Construct a weather rss thread
    public WeatherRetriever(WeatherCollector wc, String cityCode)
    {
        this.wc = wc;
        this.cityCode = cityCode;
    }

    //Retrieve weather from website
    public void run()
    {
        this.wc.add(this);

        try
        {
            URL rss = new URL("http://rss.weather.com/weather/rss/local/"+cityCode+"?cm_ven=LWO&cm_cat=rss&par=LWO_rss");
            String rss_page = this.getContent(rss);

            int end = rss_page.indexOf("For more details?");
            if(end > 0)
            {
                String weather = rss_page.substring(rss_page.indexOf(">", end-100)+1,end);
                this.wc.setLocalWeather(cityCode, weather.replace(" &deg; ","*"));
            }
            else
            {
                //city code does not exit
                this.wc.removeCityCode(cityCode);
            }
        }
        catch(MalformedURLException mue)
        {
            System.err.println(mue);
        }

        this.wc.remove(this);
    }

    //Retrieve a webpage
    public synchronized String getContent(URL url)
    {
        StringBuffer result = new StringBuffer();

        BufferedReader br = null;
        try
        {
            br = new BufferedReader(new InputStreamReader(url.openStream()));
            String line = null;
            while ((line=br.readLine())!=null)
                result.append(line+"\n");
        }
        catch(IOException ioe)
        {
            System.err.println(ioe);
        }
        finally
        {
            if(br!=null) try { br.close(); } catch(IOException ioe) { System.err.println(ioe); }
        }

        return result.toString();
    }
}

As you might have noticed, this version works with RSS, which is a better way to tackle this, since it's invented for such use. As you can see it also works with city codes which are far more reliable, you can probably look all those up and make memonics for them etc etc. I hope it gives more insight in the problem and how you can deal with it. Take the parts you think are useful and solve the problem.

Good luck,
Mark
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now