HashSet<String> noDuplicate = new HashSet<String>();
for(int i=0;i<strings.length;i++)
{
for(int a=0;a<strings2.length;a++)
{
if(noDuplicate.get(i).equals(strings2[a]))
//blahblah code here
}
}
but get doesn't work, i'm not sure how to use iterator if that's the method to use to go through the elements of a hashset. I want to do something like:
for(int i=0;i<strings.length;i++)
{
for(int a=0;a<strings2.length;a=a+2)
{
if(node_marked_array.get(i).equals(strings2[a]))
//blahblah code here
}
}
but I was told to use a hashset because of duplicate values.
Use HashSet#contains instead:
HashSet<String> noDuplicate = new HashSet<String>();
for(int i=0;i<strings.length;i++){
for(int a=0;a<strings2.length;a++){
if(noDuplicate.contains(strings2[a]))
//blahblah code here
}
}
Sets have no order by definition, and therefore can't be indexed like arrays, or lists via a get method. However you can still iterate through the elements of a Set with a for-each loop (or by using the iterator returned by the iterator() method).
For example, if I had a Set called set which contained strings "a", "b" and "c":
for (String s : set) {
System.out.println(s);
}
a
b
c
I suppose this will help
Iterator iter=hm.keySet().iterator();
while(iter.hasNext()){
String key = (String)iter.next();
if(key.equals(str)){
val1 = (String)hm.get(key);
}
}
Related
I am trying to delete one object from an ArrayList, but after iterating through the list with the for loop i'm stuck at what to do next. nameInput is a lowercase string from the user.
If i run this it prints the object from arr list equal to the input from nameInput. But I cannot understand how to go from printing that object to deleting it?
I'm sure this is a stupid question but the 50+ answers i have read and tried all seem to fail me (or more likely I fail to understand them). I have tried the list.remove and removeIf.
private ArrayList<Arr> arr = new ArrayList<>();
private void removeItem() {
for (Object arr : arr) {
if (((Arr) arr).getName().equals(nameInput())) {
System.out.println(arr);
break;
} else {
System.out.println("Error");
}
}
}
Using for loop
List<Arr> arr = new ArrayList<>();
for (Arr item : arr) {
if (item.getName().equals(nameInput())) {
arr.remove(item);
break;
}
}
If not call break after remove element, you get ConcurrentElementException
Note from #Aomine: you have to implement correct Arr.equals() method.
Using Iterator
List<Arr> arr = new ArrayList<>();
Iterator<Arr> it = arr.iterator();
while (it.hasNext()) {
Arr items = it.next();
if (item.getName().equals(nameInput())) {
it.remove();
break; // you can continue iterating and remove another item
}
}
Using Streams
List<Arr> arr = new ArrayList<>();
arr.removeIf(item -> item.getName().equals(nameInput()));
Remove all items that match given condition
This is not good to remove element from ArrayList. In case you know that you have to remove element from the middle of the List, do use LinkedList.
You are trying to remove an item while you are traversing/iterating the list in the for loop. You cannot remove an item from the list iterating it in a for loop. Use an Iterator instead and invoke arr.remove().
If you use Java 8 you could do
private void removeItem() {
arr.removeIf(t -> t.getName().equals(nameInput));
}
Note that this will remove all objects with name equal to nameInput
Also you should change your declaration of arr to
List<Arr> arr = new ArrayList<>();
A couple of things here...
The loop variable receiver type should ideally be Arr instead of Object as the list contains Arr objects. This also means you no longer need the cast you're performing.
You could remove the item via remove(Object o) but this requires overriding equals and hashcode based on name only. Another option is via an iterator but this would mean changing your code completely. Thus, to keep it as close to your code as possible you can use a for loop; get the index which the object is located and then remove.
Thus, you can do:
for(int i = 0; i < arr.size(); i++){
if (arr.get(i).getName().equals(nameInput)) {
Arr obj = arr.remove(i); // remove the item by index
System.out.println(obj); // print the object
break; // terminate the loop iteration
}
}
This is a follow up to my previous question :
Collection - Iterator.remove() vs Collection.remove()
The below two pieces of code , which apparently differs only by a single line , but one throws exception and other don't . Can you please explain the difference ?
List<String> list = new ArrayList<String>
(Arrays.asList("noob1","noob2","noob3"));
System.out.println(list);
for (String str : list) {
if (str.equals("noob2")) {
list.remove(str);
}
}
runs fine , but if i change the condition to
if (!str.equals("noob2"))
the code throws exception !
What happens in this situation is you are removing the second list element.
List<String> list = new ArrayList<String>
(Arrays.asList("noob1", "noob2", "noob3", "noob4"));
System.out.println(list);
for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) {
String str = iterator.next();
if (str.equals("noob3")) {
System.out.println("Checking "+str);
list.remove(str);
}
}
System.out.println(list);
prints
[noob1, noob2, noob3, noob4]
Checking noob1
Checking noob2
Checking noob3
[noob1, noob2, noob4]
By removing the second last element you have reduced the size to the number of elements which you have iterated over.
// from ArrayList.Itr
public boolean hasNext() {
return cursor != size;
}
This causes the loop to exit early before the concurrent modifcation check is performed in next(). If you remove any other element next() is called and you get a CME.
BTW Something which also bypasses the check is
for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) {
String str = iterator.next();
System.out.println("Checking "+str);
if (str.equals("noob2")) {
list.remove("noob1");
list.remove("noob3");
}
}
as long as the size of the collection is the same as the index it is up to, the check is not performed.
The for loop is just a simplified syntax for an iterator scan of the list. The iterator may throw an exception if the list is modified under it, but it is not guaranteed. Because of hasNext, iterators are often working one element ahead, making the first case less likely to be affected by list modification. By the time "noob2" is removed, the iterator already knows about "noob3".
Actually you should never remove collections' elements during "casual" iterating. When you have to modify your collection in some loop you have to use iterator to make these operations.
public class Test {
public static void main(String... args) {
List<String> list = new ArrayList<String>(Arrays.asList("noob1", "noob2", "noob3"));
System.out.println(list);
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
String str = iterator.next();
if (!str.equals("noob2")) {
iterator.remove();
}
}
System.out.println(list);
}
}
I suppose the exception is thown because you are trying to change a collection you are looping on... and not because the if condition.
I suggest you to create a new list only containing the items that verify the condition. Add them to the new list and avoid to change the original collection.
It's because you are trying to remove from a Collection you are currently iterating through. Making a minor alteration you can do what you want to do:
String[] strValues = {"noob1","noob2","noob3"}; // <<< Array
List<String> list = new ArrayList<String>(Arrays.asList(strValues));
System.out.println(list);
for (String str : strValues) { // << List is duplicate of array so can iterate through array
if (!str.equals("noob2")) {
list.remove(str);
}
}
That should work. Hopefully
Well, your first case doesn't throw the Exception because, the iterator returns false for Iterator.hasNext() at index 2 as you remove the element at index 1.
Iterator<String> itr = list.iterator();
while(itr.hasNext()){
String s= itr.next();
if(s.equals("noob2")){
list.remove(s); // size of the list is 2 here
System.out.println(itr.hasNext());// this returns false as it doesn't have anything at index 2 now.(on 2nd iteration )
}
}
You can test it clearly using a simple for-loop:
for (int i=0; i<list.size(); i++) {
if (list.get(i).equals("noob2")) {
System.out.println(list.get(i));
System.out.println(list.size());
list.remove(list.get(i));
System.out.println(list.size());
}
}
Output:
[noob1, noob2, noob3]
noob2
3
2
Notice the size of the list after you remove the element, which fails after incrementing. 2<2 which is false
I have a generic arraylist of an object here I want to remove certain elements, The problem is when I iterate the list with for loop, I can't do a simple sequence of remove()'s because the elements are shifted after each removal.
Thanks
Use Iterator to remove element
Like
Iterator itr = list.iterator();
String strElement = "";
while (itr.hasNext()) {
strElement = (String) itr.next();
if (strElement.equals("2")) {
itr.remove();
}
}
See here
You can iterate the list this way ...
public void clean(List<Kopek> kopeks) {
for(Kopek kopek : kopeks) {
if (kopek.isDirty())
kopeks.remove(kopek);
}
}
Which is equiv to ...
public void clean1(List<Kopek> kopeks) {
Iterator<Kopek> kopekIter = kopeks.iterator();
while (kopekIter.hasNext()) {
Kopek kopek = kopekIter.next();
if (kopek.isDirty())
kopeks.remove(kopek);
}
}
Don't do this ... (due to the reason you have already observed.)
public void clean(List<Kopek> kopeks) {
for(int i=0; i<kopeks.size(); i++) {
Kopek kopek = kopeks.get(i);
if (kopek.isDirty())
kopeks.remove(i);
}
}
However, I believe removal by index rather than by object is more efficient. Removal by object is not efficient because the list is in most cases not a hashed list.
kopeks.remove(kopek);
vs
kopeks.remove(i);
To achieve positional remove, by treating a moving target appropriately ...
public void clean(List<Kopek> kopeks) {
int i=0;
while(i<kopeks.size()) {
Kopek kopek = kopeks.get(i);
if (kopek.isDirty()) // no need to increment.
kopeks.remove(i);
else
i++;
}
}
If you have the objects that you want to remove from your ArrayList<T> you can use :
mArrayList.remove(object);
or you can use an Iterator to remove your objects:
while(iterator.hasNext()){
if(iterator.next() == some condition for removal){
iterator.remove();
}
}
You could iterate backwards and remove as you go through the ArrayList. This has the advantage of subsequent elements not needing to shift and is easier to program than moving forwards.
List<String> arr = new ArrayList<String>();
ListIterator<String> li = arr.listIterator(arr.size());
// Iterate in reverse.
while(li.hasPrevious()) {
String str=li.previous();
if(str.equals("A"))
{
li.remove();
}
}
Create a separate ArrayList of Index of the data to be removed from the original ArrayList, then remove those elements by looping over it with for loop.
ArrayList<Myobj> arr = new ArrayList<Myobj>();
for (Myobj o : arr){
arr.remove(arr.indexOf(o));
}
without using iterators also solves the issue.. All i wanted to do is get the index which are to be deleted and sort it in decending order then remove it from the list.
check the code below
Arraylist<obj> addlist = getlist();
List<Integer> indices = new ArrayList<Integer>();
for(int i=0; i<addlist.size() ;i++){
if(addlist.get(i).getDelete()){
indices.add(i);
}
}
Collections.sort(indices, Collections.reverseOrder());
for (int i : indices)
addlist.remove(i);
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.
I have an ArrayList that I want to iterate over. While iterating over it I have to remove elements at the same time. Obviously this throws a java.util.ConcurrentModificationException.
What is the best practice to handle this problem? Should I clone the list first?
I remove the elements not in the loop itself but another part of the code.
My code looks like this:
public class Test() {
private ArrayList<A> abc = new ArrayList<A>();
public void doStuff() {
for (A a : abc)
a.doSomething();
}
public void removeA(A a) {
abc.remove(a);
}
}
a.doSomething might call Test.removeA();
Two options:
Create a list of values you wish to remove, adding to that list within the loop, then call originalList.removeAll(valuesToRemove) at the end
Use the remove() method on the iterator itself. Note that this means you can't use the enhanced for loop.
As an example of the second option, removing any strings with a length greater than 5 from a list:
List<String> list = new ArrayList<String>();
...
for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); ) {
String value = iterator.next();
if (value.length() > 5) {
iterator.remove();
}
}
From the JavaDocs of the ArrayList
The iterators returned by this class's iterator and listIterator
methods are fail-fast: if the list is structurally modified at any
time after the iterator is created, in any way except through the
iterator's own remove or add methods, the iterator will throw a
ConcurrentModificationException.
You are trying to remove value from list in advanced "for loop", which is not possible, even if you apply any trick (which you did in your code).
Better way is to code iterator level as other advised here.
I wonder how people have not suggested traditional for loop approach.
for( int i = 0; i < lStringList.size(); i++ )
{
String lValue = lStringList.get( i );
if(lValue.equals("_Not_Required"))
{
lStringList.remove(lValue);
i--;
}
}
This works as well.
In Java 8 you can use the Collection Interface and do this by calling the removeIf method:
yourList.removeIf((A a) -> a.value == 2);
More information can be found here
You should really just iterate back the array in the traditional way
Every time you remove an element from the list, the elements after will be push forward. As long as you don't change elements other than the iterating one, the following code should work.
public class Test(){
private ArrayList<A> abc = new ArrayList<A>();
public void doStuff(){
for(int i = (abc.size() - 1); i >= 0; i--)
abc.get(i).doSomething();
}
public void removeA(A a){
abc.remove(a);
}
}
While iterating the list, if you want to remove the element is possible. Let see below my examples,
ArrayList<String> names = new ArrayList<String>();
names.add("abc");
names.add("def");
names.add("ghi");
names.add("xyz");
I have the above names of Array list. And i want to remove the "def" name from the above list,
for(String name : names){
if(name.equals("def")){
names.remove("def");
}
}
The above code throws the ConcurrentModificationException exception because you are modifying the list while iterating.
So, to remove the "def" name from Arraylist by doing this way,
Iterator<String> itr = names.iterator();
while(itr.hasNext()){
String name = itr.next();
if(name.equals("def")){
itr.remove();
}
}
The above code, through iterator we can remove the "def" name from the Arraylist and try to print the array, you would be see the below output.
Output : [abc, ghi, xyz]
Do the loop in the normal way, the java.util.ConcurrentModificationException is an error related to the elements that are accessed.
So try:
for(int i = 0; i < list.size(); i++){
lista.get(i).action();
}
Here is an example where I use a different list to add the objects for removal, then afterwards I use stream.foreach to remove elements from original list :
private ObservableList<CustomerTableEntry> customersTableViewItems = FXCollections.observableArrayList();
...
private void removeOutdatedRowsElementsFromCustomerView()
{
ObjectProperty<TimeStamp> currentTimestamp = new SimpleObjectProperty<>(TimeStamp.getCurrentTime());
long diff;
long diffSeconds;
List<Object> objectsToRemove = new ArrayList<>();
for(CustomerTableEntry item: customersTableViewItems) {
diff = currentTimestamp.getValue().getTime() - item.timestamp.getValue().getTime();
diffSeconds = diff / 1000 % 60;
if(diffSeconds > 10) {
// Element has been idle for too long, meaning no communication, hence remove it
System.out.printf("- Idle element [%s] - will be removed\n", item.getUserName());
objectsToRemove.add(item);
}
}
objectsToRemove.stream().forEach(o -> customersTableViewItems.remove(o));
}
One option is to modify the removeA method to this -
public void removeA(A a,Iterator<A> iterator) {
iterator.remove(a);
}
But this would mean your doSomething() should be able to pass the iterator to the remove method. Not a very good idea.
Can you do this in two step approach :
In the first loop when you iterate over the list , instead of removing the selected elements , mark them as to be deleted. For this , you may simply copy these elements ( shallow copy ) into another List.
Then , once your iteration is done , simply do a removeAll from the first list all elements in the second list.
In my case, the accepted answer is not working, It stops Exception but it causes some inconsistency in my List. The following solution is perfectly working for me.
List<String> list = new ArrayList<>();
List<String> itemsToRemove = new ArrayList<>();
for (String value: list) {
if (value.length() > 5) { // your condition
itemsToRemove.add(value);
}
}
list.removeAll(itemsToRemove);
In this code, I have added the items to remove, in another list and then used list.removeAll method to remove all required items.
Instead of using For each loop, use normal for loop. for example,the below code removes all the element in the array list without giving java.util.ConcurrentModificationException. You can modify the condition in the loop according to your use case.
for(int i=0; i<abc.size(); i++) {
e.remove(i);
}
Sometimes old school is best. Just go for a simple for loop but make sure you start at the end of the list otherwise as you remove items you will get out of sync with your index.
List<String> list = new ArrayList<>();
for (int i = list.size() - 1; i >= 0; i--) {
if ("removeMe".equals(list.get(i))) {
list.remove(i);
}
}
You can also use CopyOnWriteArrayList instead of an ArrayList. This is the latest recommended approach by from JDK 1.5 onwards.
Do somehting simple like this:
for (Object object: (ArrayList<String>) list.clone()) {
list.remove(object);
}
An alternative Java 8 solution using stream:
theList = theList.stream()
.filter(element -> !shouldBeRemoved(element))
.collect(Collectors.toList());
In Java 7 you can use Guava instead:
theList = FluentIterable.from(theList)
.filter(new Predicate<String>() {
#Override
public boolean apply(String element) {
return !shouldBeRemoved(element);
}
})
.toImmutableList();
Note, that the Guava example results in an immutable list which may or may not be what you want.
for (A a : new ArrayList<>(abc)) {
a.doSomething();
abc.remove(a);
}
"Should I clone the list first?"
That will be the easiest solution, remove from the clone, and copy the clone back after removal.
An example from my rummikub game:
SuppressWarnings("unchecked")
public void removeStones() {
ArrayList<Stone> clone = (ArrayList<Stone>) stones.clone();
// remove the stones moved to the table
for (Stone stone : stones) {
if (stone.isOnTable()) {
clone.remove(stone);
}
}
stones = (ArrayList<Stone>) clone.clone();
sortStones();
}
I arrive late I know but I answer this because I think this solution is simple and elegant:
List<String> listFixed = new ArrayList<String>();
List<String> dynamicList = new ArrayList<String>();
public void fillingList() {
listFixed.add("Andrea");
listFixed.add("Susana");
listFixed.add("Oscar");
listFixed.add("Valeria");
listFixed.add("Kathy");
listFixed.add("Laura");
listFixed.add("Ana");
listFixed.add("Becker");
listFixed.add("Abraham");
dynamicList.addAll(listFixed);
}
public void updatingListFixed() {
for (String newList : dynamicList) {
if (!listFixed.contains(newList)) {
listFixed.add(newList);
}
}
//this is for add elements if you want eraser also
String removeRegister="";
for (String fixedList : listFixed) {
if (!dynamicList.contains(fixedList)) {
removeResgister = fixedList;
}
}
fixedList.remove(removeRegister);
}
All this is for updating from one list to other and you can make all from just one list
and in method updating you check both list and can eraser or add elements betwen list.
This means both list always it same size
Use Iterator instead of Array List
Have a set be converted to iterator with type match
And move to the next element and remove
Iterator<Insured> itr = insuredSet.iterator();
while (itr.hasNext()) {
itr.next();
itr.remove();
}
Moving to the next is important here as it should take the index to remove element.
List<String> list1 = new ArrayList<>();
list1.addAll(OriginalList);
List<String> list2 = new ArrayList<>();
list2.addAll(OriginalList);
This is also an option.
If your goal is to remove all elements from the list, you can iterate over each item, and then call:
list.clear()
What about of
import java.util.Collections;
List<A> abc = Collections.synchronizedList(new ArrayList<>());
ERROR
There was a mistake when I added to the same list from where I took elements:
fun <T> MutableList<T>.mathList(_fun: (T) -> T): MutableList<T> {
for (i in this) {
this.add(_fun(i)) <--- ERROR
}
return this <--- ERROR
}
DECISION
Works great when adding to a new list:
fun <T> MutableList<T>.mathList(_fun: (T) -> T): MutableList<T> {
val newList = mutableListOf<T>() <--- DECISION
for (i in this) {
newList.add(_fun(i)) <--- DECISION
}
return newList <--- DECISION
}
Just add a break after your ArrayList.remove(A) statement