My program uses two HashmMap and they have exactly the same number of entries and the same keys.
One (tableMap) is static and never changes. The other one is dynamic (partitionMap), this means that I need to update values.
My algorithm got a problem, because seems to be adding one more entry when it is supposed to be not.
//I have a LinkedList of strings that I want to add to the HashMap partitionMap
LinkedList<String> partition = new LinkedList<String>();
for (TerminalNode terminalNode : ctx.U()) {
partition.add(terminalNode.getText());
}
//for each entry of tableMap
for(Entry<String, LinkedList<String>> entry : tableMap.entrySet())
{
//I retrieve keys and values from tableMap
String key = entry.getKey();
LinkedList<String> attributes = entry.getValue();
//the condition: if my linkedlist is included in the other do...
if(attributes.containsAll(partition))
{
//get the list of values
ArrayList<LinkedList<String>> l = partitionMap.get(key);
//but the first time is always null since I init partitionMap without values
if(l==null)
{
ArrayList<LinkedList<String>> firstLL = new ArrayList<LinkedList<String>>();
firstLL.add(partition);
partitionMap.put(key, firstLL); //BUG HERE! add one more entry instead of just updating values
}
else
{
l.add(partition);
partitionMap.put(key, l);
}
}
}
Does anybody have an idea why this is wrong?
Related
I am loading a list with some values for instance config key and config value.
I need to retrieve values for each config key from the list and then add those values into another list.
The problem is that my TO object returns these values one at a time because I am looping through the list and dcRaterName gets overridden every time the code loops through and the second list will have only one value but not all.
I want to add all the values into my second list.
List getDCRaterName= dasWebHandler.getDCRaterName(dasRequestTO);
Iterator itr = getDCRaterName.iterator();
while (itr.hasNext()) {
DasConfigTO dasConfigTO = (DasConfigTO) itr.next();
String dcRaterName = dasConfigTO.getConfigValue();
List<String> raterList = new ArrayList<>();
raterList.add(dcRaterName);
dasRequestTO.setSelectedRatersDes(raterList);
}
You should move creation of the raterList before the loop and set it inside dasRequestTO after the loop:
List<DasConfigTO> getDCRaterNames = dasWebHandler.getDCRaterName(dasRequestTO);
List<String> raterList = new ArrayList<>();
for (DasConfigTO dasConfigTO : getDCRaterNames) {
raterList.add(dasConfigTO.getConfigValue());
}
dasRequestTO.setSelectedRatersDes(raterList);
This question already has answers here:
How do I remove repeated elements from ArrayList?
(40 answers)
Closed 5 years ago.
Suppose I have an ArrayList, which has paths to the specific file to be processed. But this file can only be proccessed, if there's only one in a folder. Here's what I mean:
My ArrayList
List<String> pathsToTheFile = new ArrayList<>();
has
C:\123\456\NameOfUniqueFolder0
C:\123\456\NameOfUniqueFolder1
C:\123\456\NameOfUniqueFolder2
C:\123\456\NameOfUniqueFolder3
C:\123\456\NameOfUniqueFolder4
Suppose my 5th element is
C:\123\456\NameOfUniqueFolder0
Obviosuly, it's a duplicate of my 0 element, since the file inside this folder SHOULD NOT be proccessed at all. C:\123\456\NameOfUniqueFolder0 should be removed form the list. I can not use a SET here, because it will "remove" the duplicate, but one path to the folder will be still there, and the file inside get proccessed.
Using a hashmap here might make sense. The keys could be the file paths, and the value, if the key be present, would be the number of times the file occurs. Something like this:
Map<String, Integer> map = new HashMap<>();
map.put("C:\123\456\NameOfUniqueFolder0", 1);
map.put("C:\123\456\NameOfUniqueFolder1", 1);
map.put("C:\123\456\NameOfUniqueFolder2", 1);
map.put("C:\123\456\NameOfUniqueFolder3", 1);
map.put("C:\123\456\NameOfUniqueFolder4", 1);
Now when a new path comes along, increment its counter:
String newPath = "C:\123\456\NameOfUniqueFolder0";
Integer val = map.get(newPath);
map.put(newPath, val == null ? 1 : val.intValue() + 1);
}
At the end, you can iterate this map, and check the counter values for each key. You would then only process the files having occurred only once:
for (Map.Entry<String, Integer> entry : map.entrySet()) {
int count = entry.getValue();
if (count == 1) {
// process this file
}
// otherwise skip this path
}
You can do something like this:
public class RemoveDuplicatesFromList {
public static void main(String[] args) {
List<String> originalList = new ArrayList<String>();
//add your strings to list here
Set<String> duplicateValues = new HashSet<String>();
for(String str:originalList){
//if firstIndex != lastIndex duplicate is present
if(originalList.indexOf(str)!=originalList.lastIndexOf(str))
duplicateValues.add(str);
}
//remove duplicates from original list
originalList.removeAll(duplicateValues);
System.out.println(originalList);
}
}
You can do something like below. it will give you map of path with it's number of occurrence. eg: {C:\123\456\NameOfUniqueFolder0=2, C:\123\456\NameOfUniqueFolder1=1}
Map<String, Long> collect = pathsToTheFile.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
After this you can process only path having occurrence equal to 1.
you can use only HashSet for this if you want list in sorted order the use TreeSet
HashSet<String> set=new HashSet<String>();
set.add("C:\123\456\NameOfUniqueFolder0");
set.add("C:\123\456\NameOfUniqueFolder1");
set.add("C:\123\456\NameOfUniqueFolder2");
set.add("C:\123\456\NameOfUniqueFolder3");
set.add("C:\123\456\NameOfUniqueFolder4");
set.add("C:\123\456\NameOfUniqueFolder0");
//Traversing elements
Iterator<String> itr=set.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
your output will be
C:\123\456\NameOfUniqueFolder0
C:\123\456\NameOfUniqueFolder1
C:\123\456\NameOfUniqueFolder2
C:\123\456\NameOfUniqueFolder3
C:\123\456\NameOfUniqueFolder4
You can try this code
List<String> pathsToTheFile = new ArrayList<String>();
pathsToTheFile.add("C:/123/456/NameOfUniqueFolder0");
pathsToTheFile.add("C:/123/456/NameOfUniqueFolder1");
pathsToTheFile.add("C:/123/456/NameOfUniqueFolder2");
pathsToTheFile.add("C:/123/456/NameOfUniqueFolder0");
pathsToTheFile.add("C:/123/456/NameOfUniqueFolder3");
pathsToTheFile.add("C:/123/456/NameOfUniqueFolder4");
pathsToTheFile.add("C:/123/456/NameOfUniqueFolder0");
pathsToTheFile.add("C:/123/456/NameOfUniqueFolder0");
String newPathToBeAdded = "C:/123/456/NameOfUniqueFolder0";
while(pathsToTheFile.contains(newPathToBeAdded)) { // the new path to be added
pathsToTheFile.remove(newPathToBeAdded);
}
System.out.println(pathsToTheFile);
I'm using several techniques here, so it's hard to find help online.
I need to populate a HashMap<String, String> with values I take from part of a StringBuilder, then take the keys and add them into an ArrayList<String>, then print the list. But when I print, I get a list full of nulls. I don't know why, I thought it would print the values I got from the StringBuilder. It should print: Values taken from the hashmap keys: ABCDEFGHI. (The reason I used StringBuilder is because String is immutable, is this correct thinking too?)
Also, I figured using a loop to print the list is okay, since my keys are actually numbers.
I've never created a HashMap before, so maybe I'm missing something. Thanks for your help.
Here is my code:
// create HashMap from String
StringBuilder alphaNum = new StringBuilder("1A2B3C4D5E6F7G8H9I");
Map<String, String> myAlphaNum = new HashMap<String, String>(9);
// for loop puts key and values in map, taken from String
for (int i = 0; i < alphaNum.length();)
{
myAlphaNum.put(alphaNum.substring(i, ++i), alphaNum.substring(i, ++i));
}
if (myAlphaNum.containsKey(1))
System.out.println("Key is there.");
else
System.out.println("Key is null.");
// create ArrayList, add values to it using map keys
ArrayList<String> arrayList = new ArrayList<String>();
// for loop gets the "number" keys from HashMap to get the "letter" values
for (int j = 1; j <= myAlphaNum.size(); j++)
arrayList.add(myAlphaNum.get(j));
System.out.print("Values taken from the hashmap keys: ");
for (String list : arrayList)
System.out.print(list);
Console:
Key is null.
Values taken from the hashmap keys: nullnullnullnullnullnullnullnullnull
You are using containsKey/get with an Integer as parameter, while your map keys are defined as String. That's why you got null.
I would recommend to use a Map<Integer, String> myAlphaNum = new HashMap<Integer, String>(9); and in your loop myAlphaNum.put(Integer.parseInt(alphaNum.substring(i, ++i)), alphaNum.substring(i, ++i));. Then you'll get your desired output.
Also you could the ArrayList constructor that takes a Collection as parameter (or just sysout myAlphaNum.values()) directly.
// create ArrayList, add values to it using map keys
ArrayList<String> arrayList = new ArrayList<String>(myAlphaNum.values());
System.out.println(arrayList); //[A, B, C, D, E, F, G, H, I]
myAlphaNum has keys of type String, so passing an int to get (myAlphaNum.get(j)) will always return null.
There are several ways to iterate over the values (or keys or entries) of the map.
For example (assuming you only care about the values) :
for (String value : myAlphaNum.values())
arrayList.add(value);
// create HashMap from String
StringBuilder alphaNum = new StringBuilder("1A2B3C4D5E6F7G8H9I");
Map<String, String> myAlphaNum = new HashMap<String, String>(9);
// for loop puts key and values in map, taken from String
for (int i = 0; i < alphaNum.length();)
{
myAlphaNum.put(alphaNum.substring(i, ++i), alphaNum.substring(i, ++i));
}
System.out.println(myAlphaNum);
if (myAlphaNum.containsKey(1))
System.out.println("Key is there.");
else
System.out.println("Key is null.");
// create ArrayList, add values to it using map keys
ArrayList<String> arrayList = new ArrayList<String>();
// for loop gets the "number" keys from HashMap to get the "letter" values
for (int j = 1; j <= myAlphaNum.size(); j++)
arrayList.add(myAlphaNum.get(j+""));
System.out.print("Values taken from the hashmap keys: ");
for (String list : arrayList)
System.out.print(list);
You can try the above code. You have used string key bit while retriving Integer so it wont return anything.
So I have a hashmap which contains key as Strings and value as Integers of the count of those strings occurring in my Set
for eg I would have a hashMap as follows
Key Value
abcd 4 (meaning there are 4 duplicate strings of abcd in my Set defined someplace)
----- 13
b-b- 7
and so on..
Now what I am trying to do is remove all the empty strings entries from my HashMap. So in the above example I would want to remove all the empty strings with value 13. So my resulting HashMap would be
Key Value
abcd 4
b-b- 7
This is my code that tries to do the same. generateFeedbackMap() is function which returns the HashMap in consideration StringIterator is a class which I have defined which iterates over through each character of my Strings.
for(String key : generateFeedbackMap().keySet()) {
StringIterator it = new StringIterator(key);
int counter = 0;
while(it.hasNext()){
String nextChar = it.next();
if(nextChar.equals("-")){
counter++;
}
Iterator<Map.Entry<String, Integer>> mapIterator = generateFeedbackMap().entrySet().iterator();
if(counter >= key.length()){
while(mapIterator.hasNext()){
Map.Entry<String, Integer> entry = mapIterator.next();
if(entry.getKey().equals(key)){
mapIterator.remove();
}
}
}
}
}
So I increment the counter wherever I find a "-" character. When the counter equals my key string length which means it is an empty string, I remove it using Map Iterator but this does not remove the entry from my Map. What am I doing wrong?
generateFeedbackMap() makes it sound like you’re getting a copy of the underlying map, in which case removing a key from the copy won’t affect the underlying map. If you’re actually getting the map, then you should rename your method.
Regardless, the following would accomplish the same as your original code (but will only remove from the copy).
Map<String,Integer> feedbackMap = generateFeedbackMap();
for ( String key : feedbackMap.keySet() ) {
if ( key.matches("-+") ) {
feedbackMap.remove(key);
}
}
If you’re stuck getting a copy of the underlying map, then you do need to create your new helpfulMap. But you can still use a regular expression and other Map functions to speed things up:
Map<String,Integer> helpfulMap = new HashMap<>();
for ( Map.Entry<String,Integer> entry : generateFeedbackMap().entrySet() ) {
if ( ! entry.getKey().matches("-+") ) {
helpfulMap.put(entry.getKey(),entry.getValue());
}
}
Okay guys, I think I figured out a solution. I just copied all my current entries from oldMap to a new defined HashMap which would contain at least one letter in their keys. So essentially I got rid of all the removing and iterating over strings and just use another HashMap instead as below
Map<String, Integer> HelpfulMap = new HashMap<String,Integer>();
for(String key : generateFeedbackMap().keySet()) {
StringIterator it = new StringIterator(key);
while(it.hasNext()){
String nextChar = it.next();
if(!nextChar.equals("-")){
HelpfulMap.put(key, generateFeedbackMap().get(key));
}
}
}
I don't know what I was doing previously. I went for a good shower and came up with this idea and it worked. I love programming!
Thanks everyone for your inputs!
I have an arrayList of arrayLists. Each inner arraylist contains some objects with the format (name.version) .
{ {a.1,b.2,c.3} , {a.2,d.1,e.1} , {b.3,f.1,z.1}....}
For example a.1 implies name = a and version is 1.
So i want to eliminate duplicates in this arraylist of lists. For me , two objects are duplicate when they have the same name
So essentially my output should be
{ { a.1,b.2,c.3},{d.1,e.1} ,{f.1 ,z.1} }
Note that i want the output in the exact same form (That is , i dont want a single list with no duplicates)
Can someone provide me with an optimal solution for this?
I can loop through each inner list and place the contents in the hashset. But two issues there, i cant get back the answer in
form of list of lists.Another issue is that when i need to override equals for that object , but i am not sure if that would
break other code. These objects are meaningfully equal if their names are same (only in this case. I am not sure that would
cover the entire spectrum)
Thanks
I used Iterator.remove() to modify the collection as you move through it.
// build your example input as ArrayList<ArrayList<String>>
String[][] tmp = { { "a.1", "b.2", "c.3" }, { "a.2", "d.1", "e.1" },
{ "b.3", "f.1", "z.1" } };
List<List<String>> test = new ArrayList<List<String>>();
for (String[] array : tmp) {
test.add(new ArrayList<String>(Arrays.asList(array)));
}
// keep track of elements we've already seen
Set<String> nameCache = new HashSet<String>();
// iterate and remove if seen before
for (List<String> list : test) {
for (Iterator<String> it = list.iterator(); it.hasNext();) {
String element = it.next();
String name = element.split("\\.")[0];
if (nameCache.contains(name)) {
it.remove();
} else {
nameCache.add(name);
}
}
}
System.out.println(test);
Output
[[a.1, b.2, c.3], [d.1, e.1], [f.1, z.1]]
List<List<Pair>> inputs; // in whatever format you have them
List<List<Pair>> uniqued = new ArrayList<>(); // output to here
Set<String> seen = new HashSet<String>();
for (List<Pair> list : inputs) {
List<Pair> output = new ArrayList<>();
for (Pair p : list)
if (seen.add(p.getName()))
output.add(p);
uniqued.add(output);
}
Create a Set. Iterate over the list of lists' items. See if the item is in the Set. If it is already there, ignore it. If it isn't, add it to the Set and the list of lists.
Your method will return a new list of lists, not modify the old one. Modifying a list while iterating over it is a pain.