My hashmap contains one of entry as **key: its-site-of-origin-from-another-site##NOUN** and **value: its##ADJ site-of-origin-from-another-site##NOUN**
i want to get the value of this key on the basis of only key part of `"its-site-of-origin-from-another-site"``
If hashmap contains key like 'its-site-of-origin-from-another-site' then it should be first pick 'its' and then 'site-of-origin-from-another-sit' only not the part after '##'
No. It would be a String so it will pick up whatever after "##" as well. If you need value based on substring then you would have to iterate over the map like:
String value = map.get("its...");
if (value != null) {
//exact match for value
//use it
} else {//or use map or map which will reduce your search time but increase complexity
for (Map.Entry<String, String> entry : map.entrySet()) {
if (entry.getKey().startsWith("its...")) {
//that's the value i needed.
}
}
}
You can consider using a Patricia trie. It's a data structure like a TreeMap where the key is a String and any type of value. It's kind of optimal for storage because common string prefix between keys are shared, but the property which is interesting for your use case is that you can search for specific prefix and get a sorted view of the map entries.
Following is an example with Apache Common implementation.
import org.apache.commons.collections4.trie.PatriciaTrie;
public class TrieStuff {
public static void main(String[] args) {
// Build a Trie with String values (keys are always strings...)
PatriciaTrie<String> pat = new PatriciaTrie<>();
// put some key/value stuff with common prefixes
Random rnd = new Random();
String[] prefix = {"foo", "bar", "foobar", "fiz", "buz", "fizbuz"};
for (int i = 0; i < 100; i++) {
int r = rnd.nextInt(6);
String key = String.format("%s-%03d##whatever", prefix[r], i);
String value = String.format("%s##ADJ %03d##whatever", prefix[r], i);
pat.put(key, value);
}
// Search for all entries whose keys start with "fiz"
SortedMap<String, String> fiz = pat.prefixMap("fiz");
fiz.entrySet().stream().forEach(e -> System.out.println(e));
}
}
Prints all keys that start with "fiz" and sorted.
fiz-000##whatever
fiz-002##whatever
fiz-012##whatever
fiz-024##whatever
fiz-027##whatever
fiz-033##whatever
fiz-036##whatever
fiz-037##whatever
fiz-041##whatever
fiz-045##whatever
fiz-046##whatever
fiz-047##whatever
fizbuz-008##whatever
fizbuz-011##whatever
fizbuz-016##whatever
fizbuz-021##whatever
fizbuz-034##whatever
fizbuz-038##whatever
Related
Hey guys currently have problem with regards to removing duplicates from hashmap.
Some background:
My hashmap is in this format Map<CompositeKeyBean,ValueBean>.
CompositeKeyBean is in the form (String ID, String hashvalue);
ValueBean is an object.
So if i have a hashmap with values as such:
(ID:1,HashValue:123),Obj1
(ID:1,HashValue:234),Obj1
(ID:1,HashValue:345),Obj1
I need to remove the duplicate keys and only have items with unique IDs. currently I have come up with this, But it does not seem to work, im pretty sure i am doing something wrong.
for (Map.Entry<CompositeKeyBean, ReportDataBean> entry : list.entrySet())
{
String idvalue = entry.getKey().getCompositeKeyList().get(0);
for(int i = 1; i < list.size();i++)
{
if(list.keySet().contains(idvalue))
{
list.remove(i);
}
}
}
My solution for this one would be to declare first an another Map which will be used to hold the number of times that a certain key has appeared in the original Map. For the second time, you can iterate the same map entrySet and remove the duplicates using the declared additional Map as reference.
Map<String, Integer> numberOfInstanceMap = new HashMap<String, Integer>(); //temporary placeholder
for (Map.Entry<CompositeKeyBean, ReportDataBean> entry : list.entrySet())
{
String idvalue = entry.getKey().getCompositeKeyList().get(0);
if(!numberOfInstanceMap.containsKey(idvalue)) {
numberOfInstanceMap.put(idvalue, 1); //initialize the key to 1
} else {
numberOfInstanceMap.replace(idValue, numberOfInstanceMap.get(idValue) + 1); //add 1 to the existing value of the key
}
}
for (Map.Entry<CompositeKeyBean, ReportDataBean> entry : list.entrySet())
{
String idvalue = entry.getKey().getCompositeKeyList().get(0);
Integer i = numberOfInstanceMap.get(idValue);
if(i>1) { //remove duplicate if the key exists more than once
list.remove(idValue);
}
}
If you are expecting duplicate keys, then you can do the following way to handle it while populating the map itself:
Map<String, String> map = new HashMap<>();
if(map.containsKey("ID")){
String oldValue = map.get("ID");
//put logic to merge the value
}else{
map.put("ID","newValue");
}
I have two linked hashmap (key - String, value = String[]) which got the same size and the same keys in both linked hashmaps, I want to be able to compare values according to the key, verifying values on one linked hashmap are equals to the same values in the second linked hashmap (by key) or at least the other linked hashmap contains the values.
I am populating both of the linked hashmaps with keys and values and set it to different linked hash maps.
Example for hashmap:
Key - alert - Value (array of strings)
0 - Device_UID,Instance_UID,Configuration_Set_ID,Alert_UID
1 - a4daeccb-0115-430c-b516-ab7edf314d35,0a7938aa-9a01-437f-88ac-4b2927ed7665,96,61b68069-9de7-4b85-83cb-8d9f558e8ecb
2 - a4daeccb-0115-430c-b516-ab7edf314d35,0a7938aa-9a01-437f-88ac-4b2927ed7665,12,92757faa-bf6b-4aa3-ba6d-2e57b44f333c
3 - a4daeccb-0115-430c-b516-ab7edf314d35,0a7938aa-9a01-437f-88ac-4b2927ed7665,369,779b3294-2ca3-4613-a413-bf8d4aa05d16
and it should be at least in the second linked hash- map
String rdsColumns="";
for(String key : mapServer.keySet()){
String[] value = mapServer.get(key);
String[] item = value[0].split(",");
rdsColumns="";
for(String val:item){
rdsColumns = rdsColumns.concat(val + ",");
}
rdsColumns = rdsColumns.concat(" ");
rdsColumns = rdsColumns.replace(", ", "");
info(("Query is: "+ returnSuitableQueryString(rdsColumns, key, alertId, deviceId)));
String query=returnSuitableQueryString(rdsColumns, key, alertId, deviceId);
mapRDS.put(key, insightSQL.returnResultsAsArray(query ,rdsColumns.split(","),rdsColumns));
}
where rdsColumns are the fields I am querying in RDS data-base.
Expected: iterating over both maps and verifying at that all values according to key in the first map contains or equal in the second map.
This is the code you are looking for:
for (String keys : firstMap.keySet()) {
String[] val1 = firstMap.get(keys);
String[] val2 = secondMap.get(keys);
if (Arrays.equals(val1, val2)) {
//return true;
}
ArrayList<Boolean> contains = new ArrayList<>();
for (int i = 0; i < val1.length; i++) {
for (String[] secondMapVal : secondMap.values()) {
List<String> list = Arrays.asList(secondMapVal);
if (list.contains(val1[i])) {
contains.add(true);
break;
} else contains.add(false);
}
}
if (contains.contains(true)) {
//return true; Even a single value matches up
} else {
//return false; Not even a sinle value matches up
}
}
Basically what we have here is a HashMap<String, String>. We take the set of keys and iterate through them. Then we take the value with the key from the two sets. After we got the values we compare them and if they are the same I just print that they match. You can change this and implement this with other types of HashMaps, even where you use custom values. If I didn't understand your problem tell me and I will edit the answer.
I need iterate through hashmap and get key value which should be a string and all values within that key which is a list of strings that have strings?
Psuedo code
static HashMap<String, List<String>> vertices = new HashMap<String, List<String>>();
for (int i = 0; i < vertices.size(); i++)
{
String key = vertices.getKey at first postions;
for (int x = 0; x < size of sublist of the particular key; x++)
{
String value = vertices key sublist.get value of sublist at (i);
}
}
You can't iterate over HashMap directly, as there is no numeric index of values within HashMap. Instead key values are used, in your case of type String. Therefore the values don't have a particular order. However, if you want, you can construct a set of entries and iterate over that, using vertices.entrySet().
for (Entry<String, List<String>> item : vertices.entrySet()) {
System.out.println("Vertex: " + item);
for (String subitem : item.getValue()) {
System.out.println(subitem);
}
}
Try vertices.keySet();
It gives a Set of all keys in the map. Use it in a for loop like below
for (String key : vertices.keySet()) {
for (String value : vertices.get(key)) {
//do stuff
}
}
I am new to Java. I want to Parse the data which is in this Format
Apple;Mango;Orange:1234;Orange:1244;...;
There could be more than one "Orange" at any point of time. Numbers (1,2...) increase and accordingly as the "Orange".
Okay. After splitting it, Lets assume I have stored the first two data(Apple, Orange) in a variable(in setter) to return the same in the getter function. And now I want to add the value(1234,1244....etc) in the 'orange' thing into a variable to return it later. Before that i have to check how many oranges have come. For that, i know i have to use for loop. But don't know how to store the "Value" into a variable.
Please Help me guys.
String input = "Apple;Mango;Orange:1234;Orange:1244;...;"
String values[] = input.split(";");
String value1 = values[0];
String value2 = values[1];
Hashmap< String, ArrayList<String> > map = new HashMap<String, ArrayList<String>>();
for(int i = 2; i < values.length; i = i + 2){
String key = values[i];
String id = values[i+1];
if (map.get(key) == null){
map.put(key, new ArrayList<String>());
}
map.get(key).add(id);
}
//for any key s:
// get the values of s
map.get(s); // returns a list of all values added
// get the count of s
map.get(s).size(); // return the total number of values.
Let me try to rephrase the question by how I interpreted it and -- more importantly -- how it focuses on the input and output (expectations), not the actual implementation:
I need to parse the string
"Apple;Mango;Orange:1234;Orange:1244;...;"
in a way so I can retrieve the values associated (numbers after ':') with the fruits:
I should receive an empty list for both the Apple and Mango in the example, because they have no value;
I should receive a list of 1234, 1244 for Orange.
Of course your intuition of HashMap is right on the spot, but someone may always present a better solution if you don't get too involved with the specifics.
There are a few white spots left:
Should the fruits without values have a default value given?
Should the fruits without values be in the map at all?
How input errors should be handled?
How duplicate values should be handled?
Given this context, we can start writing code:
import java.util.*;
public class FruitMarker {
public static void main(String[] args) {
String input = "Apple;Mango;Orange:1234;Orange:1244";
// replace with parameter processing from 'args'
// avoid direct implementations in variable definitions
// also observe the naming referring to the function of the variable
Map<String, Collection<Integer>> fruitIds = new HashMap<String, Collection<Integer>>();
// iterate through items by splitting
for (String item : input.split(";")) {
String[] fruitAndId = item.split(":"); // this will return the same item in an array, if separator is not found
String fruitName = fruitAndId[0];
boolean hasValue = fruitAndId.length > 1;
Collection<Integer> values = fruitIds.get(fruitName);
// if we are accessing the key for the first time, we have to set its value
if (values == null) {
values = new ArrayList<Integer>(); // here I can use concrete implementation
fruitIds.put(fruitName, values); // be sure to put it back in the map
}
if (hasValue) {
int fruitValue = Integer.parseInt(fruitAndId[1]);
values.add(fruitValue);
}
}
// display the entries in table iteratively
for (Map.Entry<String, Collection<Integer>> entry : fruitIds.entrySet()) {
System.out.println(entry.getKey() + " => " + entry.getValue());
}
}
}
If you execute this code, you will get the following output:
Mango => []
Apple => []
Orange => [1234, 1244]
I have HashMap object contains a key x-y-z with corresponding value test-test1-test2.
Map<String,String> map = new HashMap<String,String>();
map.put("x-y-z","test-test1-test2");
map.put("x1-y1-z1","test-test2-test3");
Now I have an input string array that contains some piece of the key:
String[] rem={"x","x1"}
Based on this string array I want to remove HashMap values.
Can anyone give an efficient approach to do this operation?
List remList = Arrays.asList(rem);
for (Iterator it = map.keySet().iterator(); it.hasNext();) {
String key = (String) it.next();
String[] tokens = key.split("-");
for (int i = 0; i < tokens.length; i++) {
String token = tokens[i];
if (remList.contains(token)) {
it.remove();
break;
}
}
}
And an updated version with adding functionality based on your latest comment on this answer:
private static Map getMapWithDeletions(Map map, String[] rem) {
Map pairs = new HashMap();
for (int i = 0; i < rem.length; i++) {
String keyValue = rem[i];
String[] pair = keyValue.split("#", 2);
if (pair.length == 2) {
pairs.put(pair[0], pair[1]);
}
}
Set remList = pairs.keySet();
for (Iterator it = map.keySet().iterator(); it.hasNext();) {
String key = (String) it.next();
String[] tokens = key.split("-");
for (int i = 0; i < tokens.length; i++) {
String token = tokens[i];
if (remList.contains(token)) {
it.remove();
pairs.remove(token);
break;
}
}
}
map.putAll(pairs);
return map;
}
Edited based on edited question.
Loop through the keySet of the hashmap. When you find a key that starts with x you are looking for remove it from the map.
Something like:
for(String[] key: map.keySet()){
if(key.length>0 && x.equals(key[0])){
map.remove(key);
}
}
Assuming I understand you correctly, and you want to remove everything starting with 'x-' and 'x1-' from the map (but not 'x1111-', even though 'x1' is a prefix of 'x1111'), and efficiency is important, you might want to look at one of the implementations of NavigableMap, such as (for example) TreeMap.
NavigableMaps keep their entries in order (by natural key order, by default), and can be iterated over and searched very efficiently.
They also provide methods like subMap, which can produce another Map which contains those keys in a specified range. Importantly, this returned Map is a live view, which means operations on this map affect the original map too.
So:
NavigableMap<String,String> map = new TreeMap<String,String>();
// populate data
for (String prefixToDelete : rem) {
// e.g. prefixToDelete = "x"
String startOfRange = prefixToDelete + "-"; // e.g. x-
String endOfRange = prefixToDelete + "`"; // e.g. x`; ` comes after - in sort order
map.subMap(startOfRange, endOfRange).clear(); // MAGIC!
}
Assuming your map is large, .subMap() should be much faster than iterating over each Map entry (as a TreeMap uses a red-black tree for fast searching).
You can do the following:
Map<String,String> map = new HashMap<String,String>();
map.put("x-y-z","test-test1-test2");
map.put("x1-y1-z1","test-test2-test3");
String[] rem={"x","x1"};
for (String s : rem) {
map.keySet().removeIf(key -> key.contains(s));
}
This piece of code will remove all entries with "x" or "x1" in the map key.