St.running
St.running

Reputation: 185

How to retrieve values from ArrayList<String> if the latter is a Key in Map?

I am new to Java. Now I'm trying to work with a structure like

 Map<List<String>,String>    

..and there are difficulties with retrieving Strings from the List.

Details: I am making a simple program which takes phone numbers and checks to which country specific number belongs. It checks them via matching with regular expressions (underlying digit amount and international prefix: because prefixes (and thus - regular expressions) may be more then one - List is chosen).

So, the structure of regex is:

"^(%s)\\d{%d}", prefix, digitAmount    

There are some basic data for some numbers (Finnish, English), but user can also add new ones (example: Gonduras - prefix: 849, number of digits: 8, Gonduras (same) - prefix 49, number of digits: 7 etc.) So when you will enter a number like 893143045839 - it should find whether it matches regular expression. And if it is, return the country (a value). That's why the Map is chosen.

The code here is:

static Map <List<String>, String> data = new HashMap<List<String>, String>();
static List<String> newdata = new ArrayList<String>();

void addBasicData ()  // here I add some predefined parameters
{
List<String> finnNumbers = new ArrayList<String>();
finnNumbers.add("^(3589)\\d{6}");
finnNumbers.add("^(003589)\\d{6}");
finnNumbers.add("^(09)\\d{6}");
data.put(finnNumbers, "Finland");
}


void addNewData (String pattern, List<String> newdata)   //here I add new data from user
{
pattern();
data.put(newdata, pattern);
}    

The problem occurs further. When I want to check some number, I have to make a pattern - which should take the regex from the data. Well, it appears that I can't. Here is the method..

void numberCheck (String inputNumber)
{

// maybe I'll use Set values = data.keySet(); ? ...nah, doesn't work either :(


for (int i = 0; i<= data.size(); i++)
{
    Object c = data.get(i);
    List<String> check = (List<String>)c;
    for (int j = 0; j <check.size(); j++)   
    {

        Pattern pat = Pattern.compile(check.get(j));
        Matcher matcher = pat.matcher(inputNumber);
        if (matcher.find())
        {
            // some useful code
        }

    }


}

.., which do not work and gives NullPointerException. When I want to take a key and then try each regex as a pattern, it instead gives me an Object, not an ArrayList. That's why I am asking. I tried to use it reverse-like ( Map> ), but then I need to iterate values, and there is the same problem.

This is the point

    Object c = data.get(i);
    List<String> check = (List<String>)c;

, where everything collapses. Perhaps, I'm doing it entirely wrong and should use another classes in my case.

I would be glad, if anyone can give an advice. Thank you!

Upvotes: 0

Views: 642

Answers (2)

TheJavaCoder16
TheJavaCoder16

Reputation: 591

Instead of

static Map <List<String>, String> data = new HashMap<List<String>, String>();

You should do

static Map <String, List<String>> data = new HashMap<String, List<String>>();

Then, down when you are trying to go through the values

void numberCheck (String inputNumber)
{


    String[] keys = (String[]) data.keySet().toArray();
for (int i = 0; i<= keys.length; i++)
{
    List<String> check = (List<String>)data.get(keys[i]);
    for (int j = 0; j <check.size(); j++)   
    {

        Pattern pat = Pattern.compile(check.get(j));
        Matcher matcher = pat.matcher(inputNumber);
        if (matcher.find())
        {
            // some useful code
        }

    }


}
}

It will actually return a List. By calling data.get(i) you are asking for the VALUE of the data set at index i in the Map.

Upvotes: -1

Sneaker182
Sneaker182

Reputation: 53

I guess thats what you want to do

Map<String, List<String>> map = new HashMap<String, List<String>>();
// ...some more code...
for (List<String> regexNumbers : map.values()) {
    // regexNumbers is the value
}

Since you dont use the key in your method.

But your code whould be much more readable if you create a class - thats your structure, thats what you want, and you know (!) whats in it (even in a few years):

class CountryNumbers {
    String country;
    List<String> numbers;
}

Examplecode to print every number to a country:

List<CountryNumbers> list = fillListSomehow();
for (CountryNumbers countryNumbers : list) {
    String country = countryNumbers.country;
    System.out.println("The regexes for country " + country + " are: ");
    for (String regexNumber : countryNumbers.numbers) {
        System.out.println("  " + regexNumber);
    }
}

Upvotes: 2

Related Questions