简体   繁体   中英

Choosing the perfect data structure for the below data in java

I have to choose one data structure for my need below i am explaining the conditions there are following values

abc,def,rty,ytr,dft   which all are map to row R1B1 (actully key is combination of R1+B1)
abEERc,dFFFef,rGGty   which all are map to row R1B2 (actully key is combination of R1+B2)


  KEY                      VALUE
abc,def,rty,ytr,dft --->    R1B1
abEERc,dFFFef,rGGty --->    R1B2

now, for example, let's say, if i get ytr then i would be able to retrieve R1B1 or, let's say, i get the value rGGty then i would be able to retrieve R1B2

now the case is that matters is of search, complexity and the time taken as the things have to go in sequence

for example, it will first pick the first line to search ytr , it will first match it with abc which will not match then will have to match with def it will not again match then it will match with rty which will not also match then it will finally match with ytr and finally it will find the key R1B1 finally

similarly if the second string need to be searched lets say rGGty then it would scan first row in which it will not find the value then search would continue to second row and also in second row in the third element it would get rGGty as element then it would retrieve R1B2 as value

let's say, if put this thing in map then a sequence search will go on key and then only we will be able to find the corresponding value

Folks please advise which will be the best data structure i can implement in java in which i will have to search the keys items to find the corresponding value in very fast time also which will not hit the performance too ,the kind of data structure performance should be very high

Please advise folks

Key-value pairs can be accessed in O(1) using a HashMap . However if you use HashMap<String, String> then updating the value will be painful because Strings are immutable. This means you will have to check all entry sets and if the value matches update it. So you could create a helper class for the value and let all keys point to an instance of this class. Here is a stub with the most important functions, I guess you can add the rest yourself.

public class MyDataStructure {

  private Map<String, MyValue> key_value = new HashMap<String, MyValue>();
  private Map<String, MyValue> value_MyValue = new HashMap<String, MyValue>();

  public void set(String key, String value) {
    MyValue v = value_MyValue.get(value);
    if (v == null) { // should rarely happen, could check with containsKey
      v = new MyValue(value);
      value_MyValue.put(v);
    }
    key_value.put(key, v);
  }

  public String get(String key) {
    return key_value.get(key).getValue(); // key might not exist
  }

  public String changeValue(String oldValue, String newValue) {
    MyValue v = value_MyValue.remove(oldValue); // oldValue might not exist
    v.setValue(newValue); 
    value_MyValue.put(newValue, v);
    // will not work if newValue already exists... then you will have to merge
  }

  private class MyValue() {
    private String value;
    public MyValue(String value) {
      this.value = value;
    }
    public String getValue() {
      return value;
    }
    public void setValue(String value) {
      this.value = value;
    }
  }
}

I think its best to keep it simple until poor performance shows a need for some kind of improvement. Even if many map values are the same string, that should be ok since Java stores only one copy in heap. If the sets of keys mapped to a single string gets very large some performance improvement may be possible by doing two lookups -- first to determine set membership and second to retrieve the value of the key associated with the set. That would be easy to implement. For now here is an immediately straightforward approach:

import java.util.*;

public class HashMapDemo {

    static HashMap<String, String> map = new HashMap<String, String>();

    public static void lookup(String key, String value) {
        if (map.get(key) == value) {
            System.out.println(key + " lookup ok");
        } else {
            System.out.println(key + " lookup produced" + map.get(key));
        }
    }

    public static void main(String[] args) {
        // requirements:
        // abc,def,rty,ytr,dft ---> R1B1
        // abEERc,dFFFef,rGGty ---> abEERc

        Set<String> kset1 = new HashSet<String>(Arrays.asList("abc", "def",
                "rty", "ytr", "dft"));

        Set<String> kset2 = new HashSet<String>(Arrays.asList("abEERc",
                "dFFFef", "rGGty"));

        for (String s : kset1) {
            map.put(s, "R1B1");
        }

        for (String s : kset2) {
            map.put(s, "abEERc");
        }

        // testing value lookup with key

        for (String s : kset1) {
            lookup(s, "R1B1");
        }

        // prints:
        // abc lookup ok
        // dft lookup ok
        // def lookup ok
        // rty lookup ok
        // ytr lookup ok

        for (String s : kset2) {
            lookup(s, "abEERc");
        }

        // prints:
        // rGGty lookup ok
        // abEERc lookup ok
        // dFFFef lookup ok

        // change key "R1B1" to "XYZ"

        for (String s : kset1) {
            map.put(s, "XYZ");
        }

        // test the change

        for (String s : kset1) {
            lookup(s, "XYZ");
        }

        // prints:
        // abc lookup ok
        // dft lookup ok
        // def lookup ok
        // rty lookup ok
        // ytr lookup ok

    }
}

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