Hashmap - iterating and getting the ouput printed too many times - java

In the below code contains_All hashmap is putting the key and value for each iteration.
After for loop I am clicking on next button again putting the name and state in hashmap
so my hashmap should contain all the values for every page.
But when i am printing the hashmap
I am getting 4 lists
The key and value of 1 page.
The key value of 2 pages along with 1 page
3.The key value of 3 page along with 1 and 2
The key value of 4 pages along with previous all
NOw when I am iterating the map I am getting too many values as it is printing 1, 2,3 and4
But I want only the 4 which contains all
public static validate()
{
get value();
while (utils.isElementDisplayed(next)) {
utils.waitForElement(next, 20);
utils.click(next);
getValue();
}
public getValue{
for (int i = 0; i < allRows.size(); i++) {
names = ds_name.get(i).getText();
seName = ds_server.get(i).getText();
state = ds_state.get(i).getText();
String names_seName = name_ds.concat("_" + serverName_ds);
containsAll.put(names_seName, state);
}
System.out.println(containsAll);
Iterator it = containsAll.entrySet().iterator();
while (it.hasNext()) {
Map.Entry ent = (Map.Entry) it.next();
System.out.println("-----------------------------------------------------------");
System.out.println(ent.getKey() + "= " + ent.getValue());
Reporter.log("-----------------------------------------------------------");
Reporter.log(ent.getKey() + "= " + ent.getValue());
}
}

In order to display The key value of 4 pages along with previous all you need to move the displaying code block outside the for loop. In this case it is the block of code starting with Iterator it = containsAll.entrySet().iterator();.
Complete code sample:
public static validate() {
get value();
while (utils.isElementDisplayed(next)) {
utils.waitForElement(next, 20);
utils.click(next);
getValue();
}
public getValue {
for (int i = 0; i < allRows.size(); i++) {
names = ds_name.get(i).getText();
seName = ds_server.get(i).getText();
state = ds_state.get(i).getText();
String names_seName = name_ds.concat("_" + serverName_ds);
containsAll.put(names_seName, state);
System.out.println(containsAll);
}
Iterator it = containsAll.entrySet().iterator();
while (it.hasNext()) {
Map.Entry ent = (Map.Entry) it.next();
System.out.println("-----------------------------------------------------------");
System.out.println(ent.getKey() + "= " + ent.getValue());
Reporter.log("-----------------------------------------------------------");
Reporter.log(ent.getKey() + "= " + ent.getValue());
}
}
The reason this works and the original code doesn't is because you fill the hashmap and print it as well. In doing so you print page 1, then page 1 & 2, then page 1,2 & 3 and finally page 1,2,3 & 4. Moving the print outside the for loop only prints the finished hashmap.

Related

Java - How to implement a data structure that contains the number of clicks that were recorded on each domain AND each subdomain under it

I have a problem statement as described below:
Write a function that takes this input as a parameter and returns a data structure containing the number of
clicks that were recorded on each domain AND each subdomain under it.
For example, a click on "mail.yahoo.com" counts toward the totals for "mail.yahoo.com", "yahoo.com", and "com".
(Subdomains are added to the left of their parent domain. So "mail" and "mail.yahoo" are not valid domains.
Note that "mobile.sports" appears as a separate domain near the bottom of the input.)
Below is the input data:
String[] counts = {
"900,google.com",
"60,mail.yahoo.com",
"10,mobile.sports.yahoo.com",
"40,sports.yahoo.com",
"300,yahoo.com",
"10,stackoverflow.com",
"20,overflow.com",
"5,com.com",
"2,en.wikipedia.org",
"1,m.wikipedia.org",
"1,mobile.sports",
"1,google.co.uk"
};
Below is the expected output:
calculateClicksByDomain(counts) =>
com: 1345
google.com: 900
stackoverflow.com: 10
overflow.com: 20
yahoo.com: 410
mail.yahoo.com: 60
mobile.sports.yahoo.com: 10
sports.yahoo.com: 50
com.com: 5
org: 3
wikipedia.org: 3
en.wikipedia.org: 2
m.wikipedia.org: 1
mobile.sports: 1
sports: 1
uk: 1
co.uk: 1
google.co.uk: 1
I tried to write a solution for above problem statement:
Map<String, Integer> calculateClicksByDomainMap = new HashMap<>();
for(int i = 0; i < counts.length; i++) {
String[] seperateClickCountsAtComma = counts[i].split("\\,");
for(int j = 0; j < seperateClickCountsAtComma.length; j += 2) {
String clickCounts = seperateClickCountsAtComma[j];
String domain = seperateClickCountsAtComma[j+1];
calculateClicksByDomainMap.put(domain, Integer.parseInt(clickCounts));
}
}
for(Entry<String, Integer> domainCounts : calculateClicksByDomainMap.entrySet()) {
String domainName = domainCounts.getKey();
Integer domainCount = domainCounts.getValue();
splitStringOnOccurenceOfDot(domainName);
//System.out.println(domainName + " " + domainCount);
//String test[] = domainName.split("\\.");
//System.out.println(test[0] + "=======" + test[1] + "-----");
}
public static String splitStringOnOccurenceOfDot(String domainName) {
if(!domainName.contains(".")) {
return domainName;
}
String[] subdomain = domainName.split("\\.");
domainName = subdomain[1];
System.out.println(domainName + "===============" );
return splitStringOnOccurenceOfDot(domainName);
}
However, I'm not sure how to split the string using recursion.
Can anyone help me what is the efficient way to write code in order to get the expected output?
I there a way to solve it using recursion?
Thank you for your time.
The Map needs to ConcurrentHashMap, so that it allows concurrent updates.
First for loop with nesting can call the recursive method like below, might not need another for loop:
Map<String, Integer> calculateClicksByDomainMap = new ConcurrentHashMap<>();
for (final String count : counts) {
String[] separateClickCountsAtComma = count.split("\\,");
for (int j = 0; j < separateClickCountsAtComma.length; j += 2) {
Integer clickCount = Integer.parseInt(separateClickCountsAtComma[j]);
String domain = separateClickCountsAtComma[j + 1];
calculateClicksByDomainMap.put(domain, clickCount);
splitStringOnOccurenceOfDot(domain.substring(domain.indexOf(".")+1), clickCount, calculateClicksByDomainMap);
}
}
Rather than returning a value, recursion add/update map itself.
public static void splitStringOnOccurenceOfDot(String domainName, Integer domainCount, Map<String, Integer> calculateClicksByDomainMap) {
if(calculateClicksByDomainMap.containsKey(domainName)) {
Integer newCount = calculateClicksByDomainMap.get(domainName) + domainCount;
calculateClicksByDomainMap.put(domainName, newCount);
} else {
calculateClicksByDomainMap.put(domainName, domainCount);
}
if(domainName.contains(".")) {
splitStringOnOccurenceOfDot(domainName.substring(domainName.indexOf(".")+1), domainCount, calculateClicksByDomainMap);
}
}

JavaFx CheckTreeView how to check which item is unchecked?

I am using ControlsFX for CheckTreeView. I have lots of elements in CheckTreeView and i dont want to traverse through all the elements in this tree ( because it takes lots of time due to number of elements in the tree). Is there a method like checkTreeView.getLastUncheckedItem(); to get the last unchecked one.
Currently I am checking the number of elements that checked and comparing it with counter.
If (CountPrev > Count){
//Something Unchecked Do Stuff
}
But again, i cant find what is unchecked without traverse through all elements.
EDIT:
When user checks an item on CheckTreeView, I get that item by
String lastCheckedItem = checkTreeView.getCheckModel().
getCheckedItems().get(treeView.getCheckModel().getCheckedItems().size()-1).toString();
Now I need something like this for the unchecked item
Take a ArrayList 'allItem' and Store all TreeItems, then
after Store selected item in ObservableList 'Selecteditems' using
getCheckedItems() method, Now remove selected item in ArrayList like
below code:
Here allTreeItems is a CheckBoxTreeItem
List<String> allItem = new ArrayList<>();
for (int j = 0; j < allTreeItems.getValue().length(); j++) {
allItem.add(allTreeItems.getChildren().get(j).getValue());
}
if (CountPrev > Count) {
ObservableList<TreeItem<String>> Selecteditems = checkTreeView.getCheckModel().getCheckedItems();
allItem.remove(Selecteditems);
System.out.println("UnChecked Item :" + allItem);
for (int k = 0; k < allItem.size(); k++) {
System.out.println(allItem.get(k));
}
}
Guys thank you so much for your help!
I've accepted Calips' answer because of time and effort he gave for my question.
This is what I've been looking for:
checkTreeView.getCheckModel().getCheckedItems().addListener(new ListChangeListener<TreeItem<String>>() {
#Override public void onChanged(ListChangeListener.Change<? extends TreeItem<String>> change) {
updateText(checkedItemsLabel, change.getList());
while (change.next()) {
System.out.println("============================================");
System.out.println("Change: " + change);
System.out.println("Added sublist " + change.getAddedSubList());
System.out.println("Removed sublist " + change.getRemoved());
System.out.println("List " + change.getList());
System.out.println("Added " + change.wasAdded() + " Permutated " + change.wasPermutated() + " Removed " + change.wasRemoved() + " Replaced "
+ change.wasReplaced() + " Updated " + change.wasUpdated());
System.out.println("============================================");
}
}
});
Resource:
https://github.com/jinghai/controlsfx/blob/master/controlsfx-samples/src/main/java/org/controlsfx/samples/checked/HelloCheckTreeView.java
Stack<YourClassOfTheCheckModel> recentlyUnchcked = new Stack<YourClassOfTheCheckModel>();
yourTreeView.getSelectionModel().
selectedItemProperty().addListener( new ChangeListener() {
#Override
public void changed(ObservableValue observable, Object oldValue,
Object newValue) {
TreeItem<YourClassOfTheCheckModel> selectedItem =
(TreeItem<YourClassOfTheCheckModel>) newValue;
CheckModel checkModel = checkTreeView.getCheckModel().
bool checked = checkModel.isChecked (selectedItem);
if(checked==false){
recentlyUnchcked.push(yourObjectOfTheCheckModel);
}
}
});
Hope this will help or give you an idea though i don't know if this will work (code not tested, have no IDE right now).

How to format map data by their keys

I'm trying to format the data inside my HashMap according to their key.
I have a loop which prints data in the following format
icon: "rain"
windBearing: 239
ozone: 339.89
precipType: "rain"
humidity: 0.82
moonPhase: 0.98
windSpeed: 7.37
summary: "Light rain starting in the evening."
visibility: 16.09
cloudCover: 0.62
pressure: 1011.49
dewPoint: 1.26
time: 08-03-2016 00:00:00
temperatureMax: 8.09
All of this data is stored in a HashMap with key (for example) icon and value "rain".
How can I format all of this data according to their keys? I tried something like this
private Map formatter(Map data) {
String tmp;
for(int i = 0; i < data.size(); i++) {
if(data.containsKey("temperatureMax")) {
tmp = String.format("%s c TEST", data.get("temperatureMax"));
data.put("temperatureMax", tmp);
}
}
return data;
}
I thought something like this would format 8.09 to simply 8, but it didn't do anything. (I attempted to do what the answer here How to update a value, given a key in a java hashmap? states)
This is where I acquire the data.
public Map dailyReport() {
FIODaily daily = new FIODaily(fio);
//In case there is no daily data available
if (daily.days() < 0) {
System.out.println("No daily data.");
} else {
System.out.println("\nDaily:\n");
}
//Print daily data
for (int i = 0; i < daily.days(); i++) {
String[] value = daily.getDay(i).getFieldsArray();
System.out.println("Day #" + (i + 1));
for (String key : value) {
System.out.println(key + ": " + daily.getDay(i).getByKey(key));
dailyData.put(key, daily.getDay(i).getByKey(key));
formatter(dailyData);
}
System.out.println("\n");
}
return dailyData;
}
You should iterate through your map keys using the keySet() function of Map
for (String name:data.keySet()) {
if (name.equals("temperatureMax")) {
//Do your formatting
}
}

Add up the column values in while loop if it comes repetedly

I am creating a table from ajax and the getting of values using a while loop:
while (rstdb.next()) {
rstdb.getInt(1)+"~"+ rstdb.getInt(2);
}
In my while loop my rstdb.getInt(1) will be 2,2,2,2,2,3,3...... and second values rstdb.getInt(2) are 10,20,30,40,50,10,20,.....
I need to sum up the values specific to 2 and values specific to 3 seperate.
ie,
It means 10+20+30+40+50 =150 for 2 and 10+20 =30 for 3.
It may contain single values also for example it may have 4,5,5,6,7,7....
How can I do that?
I need something like:
while (rstdb.next()) {
rstdb.getInt(1)+"~"+ rstdb.getInt(2)+"~"+sum;
}
The variable sum should contain the sum up value.
Use map for this. You can have a map which should be mapping the specific number with sum of it's corresponding value.
int c1, c2;
Map<Integer, Integer> sum = new HashMap<>();
while (rstdb.next()) {
c1 = rstdb.getInt(1);
c2 = rstdb.getInt(2);
if(sum.containsKey(c1)) {
sum.put(c1, sum.get(c1) + c2);
// ^ will return current sum of second column
} else {
sum.put(c1, c2);
}
rstdb.getInt(1)+"~"+ rstdb.getInt(2)+"~"+sum.get(c1);
}
You can use an integer to integer map:
Map<Integer, Integer> integerMap = new HashMap<>();
while (rstdb.next()) {
int column1 = rstdb.getInt(1);
int column2 = rstdb.getInt(2);
if (integerMap.containsKey(column1)) {
int currentSum = integerMap.get(column1);
integerMap.put(column1, currentSum + column2);
} else {
integerMap.put(column1, column2);
}
}
Edit: to print out the map, you can use loop through the entrySet of the map:
for (Map.Entry entry : integerMap.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}

find the most and least used string in an ArrayList

I am having trouble finding the most and least used String in an ArrayList. The program should go through a file of Strings and count how many multiple strings there are in the list. Then print the least and most used name in the list. The ArrayList Part is finished. It is just finding the most and least common name I am having trouble with. I have no idea how to even start with it. This is what I have found online but it is not working.
Map<String, Integer> dogNames = new HashMap<>();
for (Dog dog : dogs) {
Integer value = dogNames.get(dog);
if (value == null) {
value = 0;
}
value++;
dogNames.put(dog.getName(), value);
}
int leastCommon = Integer.MAX_VALUE;
String leastCommonName = null;
for (String name : dogNames.keySet()) {
int value = dogNames.get(name);
if (value < leastCommon) {
leastCommon = value;
leastCommonName = name;
}
}
System.out.println("Least common (" + leastCommon + ") is " + leastCommonName);
The problem with your code seems to be in this line:
Integer value = dogNames.get(dog);
Your map holds dog names (String), but you are getting the entry for the Dog, which does not exist! Thus, value stays 0 even if you've seen that name before. If you fix this, you code should work.
Instead of your loop for searching the least common name, you could also define a custom Comparator based on the counts in the map and then use Collections.min and Collections.max:
Comparator<Dog> comp = new Comparator<Dog>() {
#Override
public int compare(Dog o1, Dog o2) {
return Integer.compare(dogNames.get(o1.getName()), dogNames.get(o2.getName()));
}
};
System.out.println("least " + Collections.min(dogs, comp));
System.out.println("most " + Collections.max(dogs, comp));
With Java 8, you can make it even shorter, using Comparator.comparing:
List<Dog> dogs = ...
Map<String, Integer> dogNames = new HashMap<>();
dogs.forEach(dog -> dogNames.put(dog.getName(), dogNames.getOrDefault(dog.getName(), 0) + 1));
Comparator<Dog> comp = Comparator.comparing(d -> dogNames.get(d.getName()));
System.out.println("least " + Collections.min(dogs, comp));
System.out.println("most " + Collections.max(dogs, comp));
Or even shorter, using Collections.frequency instead of building your own map, and using that to compare. Note, however, that this will be wasteful if the list is very long, since this will search the list each time anew instead of caching the counts in the map.
List<Dog> dogs = ...
Comparator<Dog> comp = Comparator.comparing(d -> Collections.frequency(dogs, d.getName()));
System.out.println("least " + Collections.min(dogs, comp));
System.out.println("most " + Collections.max(dogs, comp));
Your code should look something like this...
Map<String,int> frequencyOfDogNames = new HashMap<String,int>();
for(String dogName:dogNames) {
if(frequencyOfDogNames.contains(dogName)) {
continue;
}
frequencyOfDogNames.put(dogName, Collections.frequency(dogs, "dogName"));
}
This will give you the map of all the names with the occurrences.
Now we should loop thought the map to see which one are the max and min...
int leastCommon = Integer.MAX_VALUE;
int mostCommon = 0;
String leastCommonName, mostCommonName;
int occurrence;
for(String dogName: frequencyOfDogNames.keySet()) {
occurrence = frequencyOfDogNames.get(dogName);
if(leastCommon > occurrence){
leastCommon = occurrence;
leastCommonName = dogName;
}
if(mostCommon < occurrence){
mostCommon = occurrence;
mostCommonName = dogName;
}
}

Categories