Data structure to store data subject to keys - java

Which data structure is better to use in order to store the following data?:
"open" => "11:00", "15:00", "19:00"
"close" => "12:00", "17:00","20:00"
I would need to be able to access data in the following way:
dataStructure.get("open").get(0) => "11:00"

sounds you need something like this Map<String, List<String>>
map.get("open") would return List<String> then you can useget(index) of List's method.
Example:
Map<String, List<String>> map = new HashMap<>();(java 7)
Map<String, List<String>> map = new HashMap<List<Stirng>>();(pre java 7)
Consider your first input:
map.get("Open").get(0); would yield 11:00

Basically you can use a Map with parameters String and list to store the above .. Here list would store the number of sub values ......
Map map = new HashMap<String,list>
List list = map.get("key")
list.get(0) // will give the 0th value

If we use from existing data structure you can have a map something like this ..
Map<String,List<String>> myMap=new HashMap<String,List<String>>();
List<String> openList=new ArrayList<String>();
openList.add("11:00");
openList.add("15:00");
openList.add("19:00");
List<String> closeList=new ArrayList<String>();
closeList.add("12:00");
closeList.add("17:00");
closeList.add("20:00");
myMap.put("open",openList);
myMap.put("close",closeList);

Why not just use an array of strings and use open[0], open[1] etc? The same for an array of close strings.

Related

Should I use a flat map here or a map of key value list

I have a map of values. The values are limited to just 3 possibilities ( "A", "B", "C") . I will have some 100 entries for this map.
Map<String, String> map = new HashMap<>();
map.put("key1","A");
map.put("key2","B");
map.put("key3","C");
map.put("key4","A");
map.put("key5","B");
.
.
.
The only purpose of this map would be a function where I get the key as input and I need to return one of the three "A","B","C" or null if the key has no value. My lookup will only be based on the key here.
I cannot decide if I should repeat the values and construct a flat map as above, or to use a Map<String, List<String>> where the key would be the three values. As in
Map<String, List<String>> map = new HashMap<>();
map.put("A",Arrays.asList("key1","key2"));
map.put("B",Arrays.asList("key3","key4"));
map.put("C",Arrays.asList("key5","key6"));
Or, do I use 3 separate List<String> variables and check using contains each time. As in
List<String> A_LIST = Arrays.asList("key1","key2");
List<String> B_LIST = Arrays.asList("key3","key4");
List<String> C_LIST = Arrays.asList("key5","key6");
Also, do I use an enum/static Strings for the values here and repeat them while constructing the Map? What would be the proper way to do this? Any advice would be useful.
I'm not sure if I understood your problem. But I think the get(key) method of your map should be enough. If there is no entry in the map it will return null.
I would only change the value so it is an Enum and you can be sure that there are no other values besides A, B and C.

How to search efficiently return all the values for keys which are in a arraylist

I am having an arraylist which contains a list of numbers. I want to get all the values from the HashMap which has the keys which are in the array list.
For example say the array list contains 1,2,3,4,5,6,7,8,9 list
I want to get all the values for the keys 1,2,3,4,5,6,7,8,9 map
So currently I am implementing
for (i=0;i<list.size;i++){
map_new.put(list.get(),map.get(list.get()))
}
Is there any efficient way to do this?
Your code basically assumes that map.get(list.get()) always returns a value, you can try the following code which first filters the not null values from the list object and then adds to the new Map:
Map<String, Integer> newMap = list.stream().
filter(key -> (map.get(key) != null)).//filter values not present in Map
collect(Collectors.toMap(t -> t, t -> map.get(t)));//now collect to a new Map
In case, if map.get(list.get()) returns null, your code creates a Map with null values in it for which you might end up doing null checks, which is not good, rather you can ensure that your newly created Map always contains a value for each key.
Assuming the signature of list and the map are as following
List<Integer> list;
Map<Integer, Integer> map;
You can use following
for(int a : list){
Integer b = map.get(a);
if(b != null)
// b is your desired value you can store in another collection
}
Which is similar to the procedure you have already used.
As you can access the map in O(1) so the complexity of this code will be O(listsize)
There is not much you can do for efficiency. Still couple of small things you can do considering code example you have given above:
1) Change your for loop to
for(Long num : list)
instead of iterating using index, this will reduce you get calls over list.
2) You can update the existing map , so that you even do not need to iterate.
map.keySet().retainAll(list);
for(Long key: map.keySet()) {
System.out.println(map.get(key));
}
With this existing map will contain only those data whose keys are present in list, but you should use it carefully depending upon rest of the code logic.
You can capitalize on the fact that the keyset of a map is backed by the map itself and modifications to the keyset will reflect back to the map itself. This way, you can use the retainAll() method of the Set interface to reduce the map with a single line of code. Here is an example:
final Map<Integer, String> m = new HashMap<Integer, String>();
m.put(1, "A");
m.put(2, "B");
m.put(3, "C");
m.put(4, "D");
m.put(5, "E");
final List<Integer> al = Arrays.asList(new Integer[] { 2, 4, 5 });
System.out.println(m);
m.keySet().retainAll(al);
System.out.println(m);
This will output:
{1=A, 2=B, 3=C, 4=D, 5=E}
{2=B, 4=D, 5=E}

How to get certain information out of arraylist grouped into other lists in Java

I wrote a program, that reads multiple (similar) textfiles out of a Folder. Im splitting the information by space and store everything in one arraylist which contains data kind of this:
key1=hello
key2=good
key3=1234
...
key15=repetition
key1=morning
key2=night
key3=5678
...
Now I'm looking for a way to get those information out of this list and somehow grouped by their keys into other lists. So im looking for a way to get a result like this:
keyList1 = {hello,morning}
keyList2 = {good,night}
and so on.
So I have to check very line for a keyword such as "key1" and split the value at the "=" and go on and on.
I think, the datastructure that suits your (described) needs best is a MultiMap. It is like a map, but with the possibility to store more than one value for a key.
For example the implementation from the guava project.
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html
First, you have to iterate over the arraylist:
final Multimap<String, String> multimap = ArrayListMultimap.create();
for ( String element : arrayList ) {
String[] splitted = element.split( "=" );
multimap.put( splitted[0], splitted[1] );
}
You get a List of values the following way:
for (String key : multimap.keySet()) {
List<String> values = multimap.get(key);
}
You might want to add some sanity checks for the splitting of your Strings.
(Code is untested)
It looks like you may be looking something like this kind of grouping (assuming you have access to Java 8)
List<String> pairs = Files.readAllLines(Paths.get("input.txt"));
Map<String, List<String>> map = pairs
.stream()
.map(s -> s.split("="))
.collect(
Collectors.groupingBy(
arr -> arr[0],
LinkedHashMap::new,//to preserve order of keys
Collectors.mapping(arr -> arr[1],
Collectors.toList())));
System.out.println(pairs);
System.out.println("---");
System.out.println(map);
Output:
[key1=hello, key2=good, key3=1234, key15=repetition, key1=morning, key2=night, key3=5678]
---
{key1=[hello, morning], key2=[good, night], key3=[1234, 5678], key15=[repetition]}

Android parsing an ArrayList

I have the following ArrayList
ArrayList<HashMap<String, String>> list;
HashMap<String, String> map;
with the following values inside:
list[0] = map.put("key_0", value_0);
list[1] = map.put("key_1", value_1);
list[2] = map.put("key_2", value_2);
I would like to parse the list array and get the value of the key at a specific position.
You can get the particular map from the ArrayList> by using get() method. for example,
map = list.get(index);
And to get key of that map, you can do:
String key = map.get("key");
FYI, this is the feasible solution, i dont know why you are using key name like key_0, key_1, key_2...and so on.

Converting a Map to a List

Is there anyone who knows how to convert a Map to a List
I found here something like this :
List<Value> list = new ArrayList<Value>(map.values());
But this is going to store just the value of the Map to the List
What I want to do is : copy the Key & the Value to the List
So, do you know how to achieve this ?
This will give you a List of the Map entries:
List<Map.Entry<Key, Value>> list =
new ArrayList<Map.Entry<Key, Value>>(map.entrySet());
FYI, entries have a getKey() and a getValue() method.
One way you can do is Create a List with adding all the keys like :
List list = new ArrayList(map.keySet());
Then add all the values like :
list.addAll(map.values);
And then probably you have to access with index like:
if map size is 10 , you know that you have 20 elements in the list.
So you have to write a logic to access the key-value from the list with proper calculation of index like: size/2 something like that.
I am not sure if that helps what your requirement is.
Both #Bohemian and #dacwe are right. I'd say moreover: in most cases you do not have to create your own list. Just use map.entrySet(). It returns Set, but Set is just a Collection that allows iterating over its elements. Iterating is enough in 95% of cases.
Try storing the Map.Entrys of the map:
new ArrayList<Entry<Key, Value>>(map.entrySet());
Example:
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("Hello", 0);
map.put("World!", 1);
ArrayList<Entry<String, Integer>> list =
new ArrayList<Entry<String, Integer>>(map.entrySet());
System.out.println(list.get(0).getKey() + " -> " + list.get(0).getValue());
}

Categories