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]
Related
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 am currently working on a project where I need to check an arraylist for a certain string and if that condition is met, replace it with the new string.
I will only show the relevant code but basically what happened before is a long string is read in, split into groups of three, then those strings populate an array. I need to find and replace those values in the array, and then print them out. Here is the method that populates the arraylist:
private static ArrayList<String> splitText(String text)
{
ArrayList<String> DNAsplit = new ArrayList<String>();
for (int i = 0; i < text.length(); i += 3)
{
DNAsplit.add(text.substring(i, Math.min(i + 3, text.length())));
}
return DNAsplit;
}
How would I search this arraylist for multiple strings (Here's an example aminoAcids = aminoAcids.replaceAll ("TAT", "Y");) and then print the new values out.
Any help is greatly appreciated.
In Java 8
list.replaceAll(s-> s.replace("TAT", "Y"));
There is no such "replace all" method on a list. You need to apply the replacement element-wise; the only difference vs doing this on a single string is that you need to get the value out of the list, and set the new value back into the list:
ListIterator<String> it = DNAsplit.listIterator();
while (it.hasNext()) {
// Get from the list.
String current = it.next();
// Apply the transformation.
String newValue = current.replace("TAT", "Y");
// Set back into the list.
it.set(newValue);
}
And if you want to print the new values out:
System.out.println(DNAsplit);
Why dont you create a hashmap that has a key-value and use it during the load time to populate this list instead of revising it later ?
Map<String,String> dnaMap = new HashMap<String,String>() ;
dnaMap.push("X","XXX");
.
.
.
dnaMap.push("Z","ZZZ");
And use it like below :
//Use the hash map to lookup the temp key
temp= text.substring(i, Math.min(i + 3, text.length()));
DNAsplit.add(dnaMap.get(temp));
Lets say you have an Iterator which will contains values that you need to compare with values that are located in a separate List.
Iterator<Map.Entry<String, Object>> it = aObj.items();
while (it.hasNext()) {
Map.Entry<String, Object> item = it.next();
nameValue = item.getNameValue();
keyValue = item.getKeyValue();
System.out.println("Name: " + nameValue);
System.out.println("Value: " + keyValue);
}
This outputs:
Name: header
Value: 22222
Lets say you have a separate list (in which you want to compare the above values with):
List<Items> items = new ArrayList<>();
for (Item item : items) {
itemNameValue = item.getName();
itemKeyValue = item.getKey();
System.out.println("Name: " + itemNameValue);
System.out.println("Value: " + itemKeyValue);
}
This outputs:
Name: header
Value: 44444
Since these are different types of loops (one is a while loop and the other one is a for each loop)
how can you compare for example:
if (nameValue.equals(itemNameValue())) {
// do something?
}
I need to iterate over both collections / data structures at the same time...
Would this be the solution?
String nameValue = "";
Object keyValue = "";
String itemNameValue = "";
String itemKeyValue = "";
Iterator<Map.Entry<String, Object>> it = aObj.items();
while (it.hasNext()) {
Map.Entry<String, Object> item = it.next();
nameValue = item.getNameValue();
keyValue = item.getKeyValue();
for (Item item : items) {
itemNameValue = item.getName();
itemKeyValue = item.getKey();
}
if (nameValue.equals(itemNameValue())) {
// do something?
}
}
Basically, what I am trying to ask (in a very simplified way is this):
(1) The collection that needs to be iterated in a while loop is just test input (sample data)
(2) The array list from the second collection is really a list of data which was returned from a database call (DAO) and placed into the ArrayList.
I am trying to verify if the input from Iterator inside the while loop is the same as the values from the ArrayList (which came from a database). Since these are different data structures requiring different looping mechanisms. How could I iterate through both data structures at the same time and compare them? The second data structure (the array list) is the actual set of values that are correct.
I don't know if there's a guarantee that each iteration would be comparing the same items if I use a nested loop?
Thank you for taking the time to read this...
The problem you are facing is a direct result of a BAD Application design.
The underline incorrect assumption of this question is that the map and the list will hold the objects in the same sequence.
List --> A data structure that is ordered by not sorted
Map --> A data structure that is neither ordered nor sorted
This is not to say that these two data structures don't work well together. However, using them to store the same list should only result from an awkward program design.
Even though to answer your question, you can use the below code to accomplish this:
Iterator<Map.Entry<String, Object>> it = aObj.items();
List<Items> items = dbCall.getItems(); // Get the list of Items from the DB
int index = 0;
while (it.hasNext()) {
Map.Entry<String, Object> itemFromMap = it.next();
Item itemFromList = items.get(index);
if(itemFromMap.getNameValue().equals(itemFromList.getName()) &&
itemFromMap.getKeyValue().equals(itemFromList.getKey())){
// If you prefer a single .equals() method over &&, then you can implement a Comparator<Item>
return false;
}
index++;
}
return true;
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
I have a list of files in a array
String[] myStringArray = {"C:\file1.txt","C:\file2.txt","C:\file3.txt"};
For which I'm running a for loop to execute a command to get a value
for (String extpath: myStringArray ) {
command to get the metadata
}
Output:
modified
modified
unmodified
I'm able to get the above working. Now I need to compare each element of the output and see of they are same are different.
Should that again be created as a array and then be compared? any pointers please on the easiest approach
If you wish to store the output of each iteration of the loop in an array, you'll need a regular for loop, since you'll need the index of the array (unless you add a local counter variable).
String[] output = new String[myStringArray.length];
for (int i = 0; i < myStringArray.length; i++) {
String extpath = myStringArray[i];
output[i] = command to get the metadata
}
You could have a Map<String, Boolean> which you update as you go along. The key in this case, would be the name of the file while the value would be if the file has been modified or not, so basically:
Map<String, Boolean> map = new HashMap<String, Boolean>();
...
for (String extpath: myStringArray ) {
boolean result = ...
if(map.get(extPath) == result) {
//What to do if they are the same
}
else {
//What to do if they are different
}
map.get(i) = result; //Update the map
}
The code above should allow you to do what you are after with just 1 pass.