3

I was working on a program to validate that a map contains some set of values or not. Map API is having one method called as map.containsValue(string). But, this method verify complete String as value.

import java.util.HashMap;
import java.util.Map;

public class TestMap {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Map<Integer, String> map = new HashMap<Integer, String>();

        map.put(6, "P_T");
        map.put(7, "P_Q_T");
        map.put(8, "T");
        map.put(9, "A");
        map.put(10, "B");
        map.put(11, "P_A");
        map.put(1, "P_1");
        map.put(2, "Q");
        map.put(3, "P_Q");
        map.put(4, "Q_T");
        map.put(5, "T");

        System.out.println("Map is = "+map);

        System.out.println("Result is = " + map.containsValue("P"));
    }
}

Above program will return output as :

Map is = {1=P_1, 2=Q, 3=P_Q, 4=Q_T, 5=T, 6=P_T, 7=P_Q_T, 8=T, 9=A, 10=B, 11=P_A}
Result is = false

My requirement is that Result should be true as, Map contains keys 1, 3, 6, 7, 11, which contains char P as value.

I have a solution, that i could use loop to verify each value and then find indexOf each value for P char.

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class TestMap {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Map<Integer, String> map = new HashMap<Integer, String>();

        map.put(6, "P_T");
        map.put(7, "P_Q_T");
        map.put(8, "T");
        map.put(9, "A");
        map.put(10, "B");
        map.put(11, "P_A");
        map.put(1, "P_1");
        map.put(2, "Q");
        map.put(3, "P_Q");
        map.put(4, "Q_T");
        map.put(5, "T");

        System.out.println("Map is = " + map);

        System.out.println("Result is = " + map.containsValue("P"));

        System.out.println("Result from loop is = " + verifyMap(map));

    }

    private static boolean verifyMap(Map<Integer, String> map) {
        // TODO Auto-generated method stub
        Set<Integer> set = map.keySet();
        Iterator<Integer> itr = set.iterator();
        while (itr.hasNext()) {
            Integer integer = (Integer) itr.next();
            String str = map.get(integer);
            if (str.indexOf("P") >= 0)
                return true;
        }
        return false;
    }
}

I have evaluated string with indexOf method instead of contains, which is marginally faster . String.class file from JAVA7

See this question

This return the desired result as:

Result from loop is = true

But, I just want to know, is there any other way to verify same?

Community
  • 1
  • 1
Rohit Batta
  • 482
  • 4
  • 16

4 Answers4

6

You can write your method with less code using Java 8 Streams :

private static boolean verifyMap(Map<Integer, String> map) {
    return map.values().stream().anyMatch(str->str.indexOf("P") >= 0);
}

Even in Java 7 your method can be shorter :

private static boolean verifyMap(Map<Integer, String> map) {
    for (String str : map.values()) {
        if (str.indexOf("P") >= 0)
            return true;
    }
    return false;
}
Eran
  • 387,369
  • 54
  • 702
  • 768
  • Thanks, @Eran. I am using java7 for my program. Yes, I could use shorter method, that is the syntax. But, my question was, is there any `util` or `library` which have this kind of functionality inbuilt to verify value as `full text search` – Rohit Batta Nov 20 '15 at 06:55
  • @RohitBatta If there is, I'm not aware of it. – Eran Nov 20 '15 at 06:59
0

You can also try this:

 private static boolean verifyMap(Map<Integer, String> map) {
    for(String val:map.values())
    {
      if( val.contains("P"))
      {
        return true;
      }
    }

   return false; 
}
Ajith John
  • 360
  • 2
  • 15
  • Yes, this could be done. But, i want to avoid loop for performance reasons. In your snippet, you have evaluated `string` with `contains` method. I have evaluated with `indexOf`, which is marginally faster than `contains` . [See this question](http://stackoverflow.com/questions/498686/is-string-contains-faster-than-string-indexof) – Rohit Batta Nov 20 '15 at 06:57
  • Check this thread http://stackoverflow.com/questions/10714376/which-string-method-contains-or-indexof-1 – Ajith John Nov 20 '15 at 07:04
  • And your link is about c#. – Ajith John Nov 20 '15 at 07:06
  • Yes it is about C# . But logic remains the same. See the sceenshot attached in question for reference – Rohit Batta Nov 20 '15 at 07:16
  • Both have almost same performance. that's why i have mentioned marginal. thanks – Rohit Batta Nov 20 '15 at 07:19
  • Both have same performance.And you should chose,which one has more clarity in code.that's it. – Ajith John Nov 20 '15 at 07:24
0

I was able to find out a way by which I could verify partial char in the values of map. I have used Matcher API from Java-7. Thanks to @Eran, for a hint related to Java8.

Below is the code snippet, i am using now.

private static boolean verifyMap(Map<Integer, String> map) {
    Matcher matcher = Pattern.compile(".*p.*", Pattern.CASE_INSENSITIVE)
            .matcher(map.values().toString());
    return matcher.matches();
}
Rohit Batta
  • 482
  • 4
  • 16
0

Why are you searching the values of a hashtable in the first place? That's guaranteed to be at least O(N) (and stringifying the whole thing, as you suggested elsewhere, is even worse since it also requires O(N) extra allocations and aa large constant factor as well). What you want is to build an inverted index which maps backward (from strings to integers). Most likely you want to use a trie, which will give you O(M) (where M is the maximum string length) lookup performance.

Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135