简体   繁体   中英

implementation of put method in a hashmap

I was reading about maps in java. I did this code.

public class Test {

    private HashMap<String, Integer> h;
    private int dataCount;

    public Test() {

        h = new HashMap<String, Integer>();
        dataCount = 0;
    }

    public String getNumber(String name) {

        for (String k : h.keySet()) {
            if (k.equals(name)) {
                Integer v = h.get(k);
                return k+" "+v;
            }
        }
        return null;
    }

    public void putNumber(String name, Integer number) {
        Iterator<String> i = h.keySet().iterator();
        if (i.equals(name)) {
            h.put(name, number);
        } 
        h.put(name, number);
        dataCount++;

    }

//  public void putNumber(String name, Integer number) {
//      
//      for (String k : h.keySet()) {
//          if(k.equals(name)) {
//              h.put(k, number);
//          } 
//              h.put(name, number);
//              dataCount++;
//          }
//  }


    public static void main(String[] args) {

        Test t = new Test();
        t.putNumber("ali", 123);
        t.putNumber("ala", 658);
        t.putNumber("baba", 987);
        t.putNumber("ali", 666);

        System.out.println(t.dataCount);
        System.out.println(t.getNumber("ali"));
        System.out.println(t.h);

    }

}

When I run this code I get :

4
ali 666
{baba=987, ala=658, ali=666}

It should not be like that, I want it to be like this :

3
{ali 666, baba=987, ala=658}

in my putNumber method when a name is already exisitng in the map so I just want to change its number and not add the same name again with a new number.

I have also that my second putNumber method with the for each loop does not nork at all. When I run the code with the putNumber method (for each one) I get this:

0
null
{}

Thanks

Your putNumber method contains multiple errors :

  • i.equals(name) you're comparing a String with an Iterator<String> . That won't work
  • if your condition was ever true, you would execute h.put twice (which isn't problematic, but clearly is useless)
  • you would always execute dataCount++ (when it should be the only thing conditioned)

Here's what I would do instead :

public void putNumber(String name, Integer number) {
    if (!h.containsKey(name)) {
        dataCount++;
    }
    h.put(name, number);
}

Alternatively, using an HashTable (where null isn't an authorized value) instead of an HashMap would make it possible to rely on the return value of HashTable.put(key, value) which will return null if there was no previous mapping for the key :

public void putNumber(String name, Integer number) {
    if (h.put(name, number) == null) {
        dataCount++;
    }
}

Also note that the HashMap class defines a .size() method which might make maintaining a dataCount variable useless.

I think your putNumber method is wrong, it should be something like

public void putNumber(String name, Integer number) {
    Iterator<String> i = h.keySet().iterator();
    if (i.equals(name)) {
        h.put(name, number);
    } else {
        h.put(name, number);
        dataCount++;
    }
}

Right now, if the key is already present, it will still increase the dataCount .

However, there's another problem with this code. One of the main advantages of using a HashMap is that you can look up the keys very fast; you don't need to iterate over the keyset, you can just use h.containsKey(name) and h.get(name) . Also, it has a built-in size() method with the same properties as your dataCount .

You are not using HashMap correctly.

There's no point in iterating over the keySet to locate a specific key. That's what get , put and containsKey are for.

public void putNumber(String name, Integer number) { 
    if (h.put(name, number) == null)
        dataCount++; // increment the counter only if the name was not already in the Map
}

public String getNumber(String name) {
    Integer v = h.get(name);
    return v == null ? null : name+" "+v;
}
public void putNumber(String name, Integer number) {
    Iterator<String> i = h.keySet().iterator();
    if (i.equals(name)) {
        h.put(name, number);
    } 
    h.put(name, number);
    dataCount++;
}

1) In any cases, you put the element in the map. So you should not repeat yourself.
2) Besides dataCount is incremented at each time even when no new value is added.
3) if (i.equals(name)) doesn't compare all keys but compare the iterator value with the name parameter.

Try that :

public void putNumber(String name, Integer number) {
     if (!h.containsKey(name)){
         dataCount++;    
     }
     h.put(name, number);               
 } 

Besides, getNumber() could be also simplify since by using one more time the containsKey() method of the map.

public String getNumber(String name) {     
     if (h.containsKey(name)){
         Integer v = h.get(k);
         return k+" "+v;    
     }               
    return null;
}

Your putNumber method makes little sense:

public void putNumber(String name, Integer number) {
    Iterator<String> i = h.keySet().iterator(); //i is an iterator
    //this returns always false, you are comparing an iterator to a string
    if (i.equals(name)) {
        h.put(name, number);
    }

    //this code is always executed
    h.put(name, number);
    dataCount++;
}

What you should do is something like:

public void putNumber(String name, Integer n) {
    h.put(name,n);
    dataCount=h.size();
}

Or, if you want something more "manual":

public void putNumber(String name, Integer n) {
    if (h.get(name)==null) {
        dataCount++;
    }
    h.put(name,n);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM