I want to remove a specific value from the hashmap and the key from that value. Look, for example if I have
hashMap.put(cold, frozen)
hashMap.put(cold,hard)
, in my graphic interface i will have cold=[frozen,hard].If I want to erase hard I want cold = [frozen] to stay
My hashMap is private HashMap<String,ArrayList<String>> hashMap ;
Here is what I tried but it's not good enough because if I have at 2 different key the value i want to remove, it only removes the value for the first and if I have for ex cold=[frozen,hard] and I erase hard it doesn't keep cold=[frozen];
for(String key : hashMap.keySet()){
int siz = hashMap.get(key).size();
for(int i = 0; i< siz;i++){
if(hashMap.get(key).get(i).equals(cuvant)){
s.remove(hashMap.get(key).get(i));
siz--;
hashMap.remove(key);
}
}
}
I forgot to mention that s is the arrayList with the values.
Are you putting an ArrayList with the values in a hashmap?
If so, then check for list size first:
if (! hashMap.get(key).isEmpty()){
hashMap.get(key).remove(ValueToRemoved)
}
add a condition
if (hashMap.get(key).isEmpty())
before
hashMap.remove(key);
This will ensure you delete a key only if the list associated with it is completely empty.
Also, make sure you do NOT keep iterating (the inner loop) after removing an element from the list if you use a for-each loop, it will get you a ConcurrentModificationException. If your list can have the same value multiple times (and should be removed multiple times), use the Iterator API rather than for-each loop.
Try this :-
HashMap<String, ArrayList<String>> m = new HashMap<>();
Iterator<Map.Entry<String,ArrayList<String>>> iter = m.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String,ArrayList<String>> entry = iter.next();
ArrayList<String> list = entry.getValue();
for(int i = 0 ; i < list.size() ; i++){
if(list.get(i).equals(cuvant)){
list.remove(i);
}
}
if(list.isEmpty())
iter.remove();
}
Related
I am relatively unexperienced using such Java code. For getting forward in my Selenium automation I want to iterate through a Map>.
Right now I try to get near that iteration with the following code:
static Map<String, List<WebElement>> map = new Map<String, List<WebElement>>;
for (Map.Entry<String, List<WebElement>> entry : map.entrySet()) {
for (int i = 0; i < entry.getValue().size(); i++) {
*need to find code*
}
}
My intention is to iterate through all the WebElements within the Value of one Key within map
Will "entry.getValue().size()" get the Size of the List in that case? And how may I get a certain item out of the list in such a case? Any better solutions maybe?
Best regards
You can access both the key and the value from each map entry and do whatever you need. The key in this case is a string, and its value is a List<WebElement>. Once you have the list in hand, you can access its size and iterate over it.
for (Map.Entry<String, List<WebElement>> entry : map.entrySet()) {
String key = entry.getKey();
List<WebElement> list = entry.getValue();
// to iterate over the list, you can try
for (int i=0; i < list.size(); ++i) {
WebElement we = list.get(i);
// do something with this web element
}
}
My intention is to iterate through all the WebElements within the Value of one Key within map
That should be easy enough:
for( WebElement element : map.get(key) ) {
//do whatever is appropriate
}
There's one problem with the above: if get(key) returns null (either the key is not mapped or the map contain's the value null for that key) you get a NullPointerException. To fix that could first get the map, check if you didn't get null, then iterate:
List<WebElement> list = map.get(key);
if( list != null ) {
for( WebElement element : list ) {
//do whatever is appropriate
}
}
You might also want to have a look at Guava's ListMultimap, which always will return a collection/list on get() and makes handling maps with list values a lot easier.
Will "entry.getValue().size()" get the Size of the List in that case?
Yes since entry.getValue() should return a List unless you mapped null for the given key. And since you get a List the call to size() will return the list's size.
And how may I get a certain item out of the list in such a case?
If you know the index of that element just check whether the list actually contains that index, i.e. whether index >= 0 && index < list.size(). Then just get it with list.get(index).
If you don't know the index you need to iterate over the list and inspect each element until you reach the end or found the element you need. Alternatively, if you can sort the list by the property you're checking, you could also use binary search to locate the element, if it exists.
Note, though, that LinkedList has linear cost for get(index) and thus isn't well suited for getting by index or binary search, at least not if the list contains many elements.
I have to compare two Excel files (with different data) and create two new Excel tables:
Table 1 contains all matching entries
Table 2 contains all entries that not match
Therefore I iterate over both Excel files and store the matching entries in a LinkedHashMap. In a second LinkedHashMap I store all entries from the Excel file. With this two Maps I want to identify the delta.
To identify the delta I compare both lists and now want to remove all entries from the complete list, if the entry is already in the list with the matching ones.
I tried different solutions - all with the result that the code is running but never an entry is really removed. Can anyone help please?
Heres my code:
// This code fills both Maps
LinkedHashMap<String, String> liste_matches = new LinkedHashMap<String, String> ();
LinkedHashMap<String, String> liste_complete = new LinkedHashMap<String, String> ();
while(worksheet1.getLastRowNum() >= j){
liste_complete.put(String.valueOf(worksheet1.getRow(j).getCell(18)), "");
// Counter for loop, loops trough Telekom datasets
int i = 1;
while(worksheet2.getLastRowNum() >= i)
{
if(String.valueOf(worksheet1.getRow(j).getCell(18)).equals(String.valueOf(worksheet2.getRow(i).getCell(9))))
{
if(!liste_matches.containsKey(String.valueOf(worksheet1.getRow(j).getCell(18)))){
liste_matches.put(String.valueOf(worksheet1.getRow(j).getCell(18)), "");
}
}
}
// build Excel table
}
This is my code I used to compare both lists and remove all entries from liste_complete that are already in liste_matches.
I first tried this (I inserted the ArrayList for my second try...). It's running but without any effect to the list.
ArrayList list = new ArrayList();
for(Map.Entry<String,String> keyDelta : liste_complete.entrySet())
{
for(Map.Entry<String,String> key : liste_matches.entrySet()){
if(keyDelta.equals(key)){
liste_complete.remove(keyDelta);
list.add(entry.getValue());
}
}
}
Afterwards I tried this but also without any effect to the List:
for(int c = 0; c < list.size(); c++)
{
String str = list.get(c);
liste_complete.remove(str);
}
I found this solution in StackOverflow, but that returns java.lang.IllegalStateException
Iterator<Map.Entry<String,String>> iter = liste_complete.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String,String> entry = iter.next();
for(Map.Entry<String,String> key : liste_matches.entrySet()){
if(key.getValue().equalsIgnoreCase(entry.getValue())){
iter.remove();
}
}
}
AFAIK you can't remove element from a list you're iterating on.
I suggest you 2 solutions:
iterate on your lists to check for matching keys and store the match in the third list; then iterate on the third list and remove from liste_complete
refactor the first piece of code of your question so that you store in one list the matching values and in the other the non-matching. Pseudo code could be:
for worksheet1 row
for worksheet2 row
if(match)
liste_matches.add(...)
else
liste_non_matches.add(...)
In this way you do not have to remove elements afterwards.
Thanks a lot for your hints.
I already debugged the code but didn't understand the problem - I think it really was a problem of the complex input data.
I did not compare the keys via key.getKey() but only with key and that seems to cause problems in the comparison. Anyway, my code runs with this snippet:
for(Map.Entry<String,String> keyDelta : liste_Complete.entrySet()){
if(!liste.containsKey(keyDelta.getKey())){
delta_liste.put(String.valueOf(keyDelta), "");
}
}
I am attempting to search through an array list to find a value (which may reoccur) and remove all instances of that value. I also would like to remove from a separate array list, values that are at the same location. Both ArrayLists are ArrayList<String>.
For example I am looking for the number 5 in ArrayList2:
ArrayList 1 ArrayList2
cat 1
pig 2
dog 5
chicken 3
wolf 5
Once I find the number 5, in both locations, I would like to remove dog and wolf from ArrayList1. My code has no errors but it doesn't seem to be actually removing what I am asking it.
//searching for
String s="5";
//for the size of the arraylist
for(int p=0; p<ArrayList2.size(); p++){
//if the arraylist has th value of s
if(ArrayList2.get(p).contains(s)){
//get the one to remove
String removethis=ArrayList2.get(p);
String removetoo=ArrayList1.get(p);
//remove them
ArrayList2.remove(removethis);
ArrayList1.remove(removetoo);
}
}
When I print the arrayLists they look largely unchanged. Anyone see what I am doing wrong?
When you are both looping and removing items from an array, the algorithm you wrote is incorrect because it skips the next item following each removal (due to the way in which you increment p). Consider this alternative:
int s = 5;
int idx = 0;
while (idx < ArrayList2.size())
{
if(ArrayList2.get(idx) == s)
{
// Remove item
ArrayList1.remove(idx);
ArrayList2.remove(idx);
}
else
{
++idx;
}
}
If you want to iterate over a collection and remove elements of the same collection, then you'll have to use an Iterator, e.g.:
List<String> names = ....
List<Integer> numbers = ....
int index = 0;
Iterator<String> i = names.iterator();
while (i.hasNext()) {
String s = i.next(); // must be called before you can call i.remove()
if (s.equals("dog"){
i.remove();
numbers.remove(index);
}
index++;
}
EDIT
In your case, you'll have to manually increment a variable to be able to remove items from the other List.
You could use two iterators:
Iterator<String> i1 = arrayList1.iterator();
Iterator<Integer> i2 = arrayList2.iterator();
while (i1.hasNext() && i2.hasNext()) {
i1.next();
if (i2.next() == s) {
i1.remove();
i2.remove();
}
}
Though as has been pointed out yet, it would probably be easier to use a map.
I think the contains method compares the two objects. However, the object "s" is different from the object in the ArrayList. You should use typed arrays (i.e. ArrayList) and make sure to compare values of each objects, not the objects themselves ...
You should declare your list as follows -
List<String> list1 = new ArrayList<String>();
//...
List<Integer> list2 = new ArrayList<Integer>();
//...
And instead of contains method use equals method.
Also to remove while iterating the lists use Iterator which you can get as follows -
Iterator<String> it1 = list1.iterator();
Iterator<Integer> it2 = list2.iterator();
//...
You might want to check the indexOf() method of ArrayList, but you have to be careful when removing from a list while iterating on it's elements.
Here's a straight forward solution:
List<Integer> origNums = new ArrayList<Integer>(nums);
Iterator<String> animalIter = animals.iterator();
Iterator<Integer> numIter = nums.iterator();
while (animalIter.hasNext()) {
animalIter.next();
// Represents a duplicate?
if (Collections.frequency(origNums, numIter.next()) > 1) {
// Remove current element from both lists.
animalIter.remove();
numIter.remove();
}
}
System.out.println(animals); // [cat, pig, chicken]
System.out.println(nums); // [1, 2, 3]
I agree with Makoto, using Map maybe more beneficial. If you will be searching only using the values of ArrayList2, then you have multiple values for one key.
For example, 5 refers to dog and wolf. For this you can add a list of values to the key - 5.
HashMap aMap = HashMap();
ArrayList key5 = new ArrayList();
key5.add("dog");
key5.add("wolf");
aMap.put(5, key5);
So when you need to remove all values for 5, you do
aMap.remove(5);
And it will remove the list containing dog and wolf.
I have written following code which is resulting in concurrent modification exception. How can I prevent it ? The idea is to escape all values of the Map and reconstruct the object (dO) back with new param map.
try {
Map<String,String[]> paramMap = dO.getParameterMap();
Set<Map.Entry<String, String[]>> entries = paramMap.entrySet();
Iterator<Map.Entry<String, String[]>> it = entries.iterator();
while (it.hasNext()) {
Map.Entry<String, String[]> entry = it.next();
String[] values = entry.getValue();
List<String> valList = new ArrayList<String>();
if (values != null) {
for (String value : values) {
valList.add(escapeHTML(value));
}
dO.removeParameter(entry.getKey());
//Please note that Parameter is a hashMap so , Is it required to remove the entry first before inserting or it will replace the new value associated with key . How it works in Java ?
dO.addParameter(entry.getKey(),valList.toArray(new String[valList.size()]));
}
}
}
the exception is thrown because you are adding/removing things from the map while you are iterating it:
dO.removeParameter(entry.getKey());
dO.addParameter(entry.getKey(),valList.toArray(new String[valList.size()]
you should use iterator.remove() instead.
Not sure you need to alter the keys of Map, it appears all you want to do is alter the values in the arrays.
for(String[] values: dO.getParameterMap().values())
for (int i = 0; i < values.length; i++)
values[i] = escapeHTML(values[i]);
I would make sure the Map does have null values stored. But if you can't change this you will need to add if(values != null)
You should remove/add only if you are changing a key in a map. As I see in the code, you are changing only value. Hence you could use entry.setValue(...) instead.
ConcurrentModificationException is thrown when you use fail-fast iterators (eg: entries.iterator() is fail-fast iterator). What they do is they iterate over original collection object.
To be able to modify and iterate over a collection object you can use fail-safe iterator (eg: List<Book> books = new CopyOnWriteArrayList<>()) This will take a copy inside memory while iterating over the elements and even you will be able to modify it.
I'm a relatively new Java programmer and I'm having difficuly removing more than one element from an ArrayList. Ideally I'd like to do something like this:
ArrayList ar1 = new ArrayList();
ar1.add(...)
ar1.add(...)
ar1.add(...)
ar1.add(...)
for (int i = 0; i < 2; i++){
ar1.remove(i);
}
I think iterator might help, but I can't find an example that matches close enough to what I'm trying to do. Any help would be appreciated. Thanks.
Here's what you want to do:
ar1.subList(0, 2).clear();
This creates a sublist view of the first 2 elements of the list and then clears that sublist, removing them from the original list. The subList method exists primarily for this sort of thing... doing operations on a specific range of the list.
You can certainly do that
ArrayList ar1 = new ArrayList();
ar1.add("a");
ar1.add("b");
ar1.add("c");
ar1.add("d");
for (int i = 0; i < 2; i++) {
ar1.remove(i);
}
System.out.println(ar1);
Only pay attention that after you remove first element, other elements shift. Thus, calling
ar1.remove(0);
ar1.remove(1);
will effectively remove first and third elements from the list. This will delete first two elements, though:
ar1.remove(0);
ar1.remove(0);
For indexed removals from a list, you need to count backwards:
for (int i = 1; i >= 0; i--)
otherwise, your first removal shifts the items "above" it in the collection and you don't wind up removing the items you think you are removing.
You can use Collection.removeAll(toRemove) if you have a separate list of objects to remove.
http://download.oracle.com/javase/6/docs/api/java/util/Collection.html
If your collection is indexed based, like ArrayList is, you can call
remove(index)
to remove the element at the index. You can do that in a loop, but beware that removing shifts all the indexes as another answer points out.
If all you want to do is remove the first two elements from the list, then
list.remove(0);
list.remove(0);
should do it.
If you know the indexes of the items you want to remove, you can remove them in reverse order, without worrying about shifting indexes:
ArrayList ar1 = new ArrayList();
ar1.add("a");
ar1.add("b");
ar1.add("c");
ar1.add("d");
int[] indexesToRemove = {0,2,3};
Arrays.sort(indexesToRemove);
for (int i=indexesToRemove.length-1; i>=0; i--) {
ar1.remove(indexesToRemove[i]);
}
You could try this:
List<Whatever> l = new ArrayList<Whatever>();
l.add(someStuff);
Iterator<Whatever> it = l.iterator();
int i = 0;
while (i < 2 && it.hasNext()) {
it.next();
it.remove();
i++;
}
Or, more generally:
List<Whatever> l = new ArrayList<Whatever>();
l.add(someStuff);
Iterator<Whatever> it = l.iterator();
while (it.hasNext()) {
Whatever next = it.next();
if (shouldRemove(next)) {
it.remove();
}
}
EDIT: I guess it depends if you are trying to remove particular indices or particular objects. It also depends on how much logic you need to decide if something should be removed. If you know the indices then remove them in reverse order. If you have a set of Objects to be removed, then use removeAll. If you want to iterate over the list and remove objects that match a predicate then use the above code.