I'm wondering for the simplest method for how to run a specific function for each object in an array (or other list type)
My goal is to be able create a list of objects, and have each object run a specific function as it passes through the iterator.
I've tried a for loop on an arraylist
for (int i = 0; i < testList.size(); i++)
{
this = textList.get(i);
this.exampleFunction();
}
But this gives me a 'Variable expected' error
Assuming you're using Java 8+, and you have a Collection<TypeInList> you could call Collection.stream() and do a forEach on that. Like,
testList.stream().forEach(TypeInList::function);
Your current approach is trying to do things with this that cannot be done. It could be fixed like,
for (int i = 0; i < testList.size(); i++)
{
TypeInList that = testList.get(i); // this is a reserved word.
that.function();
}
or
for (TypeInList x : testList) {
x.function();
}
There are multiple ways to iterate through a list, but the easiest I personally find is like this:
Assuming that your list contains String objects e.g.:
List<String> list = new ArrayList();
list.add("Hello");
list.add("World");
for(String current : list){
System.out.println(current);
}
The loop will iterate twice, and console will output the following:
Hello
World
This approach doesn't rely on indexes (as how you're using it in your question), as such I find it easy to use for iterating through a single list.
However the disadvantage is that if you have 2 separate lists that you would like to iterate through, the lack of indexes makes it a bit more complicated. The easier approach for iterating through multiple lists would be using the traditional approach, something like this:
for(int i=0; i<list.size(); i++){
int x = list1.get(i);
int y = list2.get(i);
}
As such your use-case really determines the ideal method you can adopt.
I am looping through a list A to find X. Then, if X has been found, it is stored into list B. After this, I want to delete X from list A. As speed is an important issue for my application, I want to delete X from A without looping through A. This should be possible as I already know the location of X in A (I found its position in the first line). How can I do this?
for(int i = 0; i<n; i++) {
Object X = methodToGetObjectXFromA();
B.add(X);
A.remove(X); // But this part is time consuming, as I unnecessarily loop through A
}
Thanks!
Instead of returning the object from yhe method, you can return its index and then remove by index:
int idx = methodToGetObjectIndexFromA();
Object X = A.remove(idx); // But this part is time consuming, as I unnecessarily loop through A
B.add(X);
However, note that the remove method may be still slow due to potential move of the array elements.
You can use an iterator, and if performance is an issue is better you use a LinkedList for the list you want to remove from:
public static void main(String[] args) {
List<Integer> aList = new LinkedList<>();
List<Integer> bList = new ArrayList<>();
aList.add(1);
aList.add(2);
aList.add(3);
int value;
Iterator<Integer> iter = aList.iterator();
while (iter.hasNext()) {
value = iter.next().intValue();
if (value == 3) {
bList.add(value);
iter.remove();
}
}
System.out.println(aList.toString()); //[1, 2]
System.out.println(bList.toString()); //[3]
}
If you stored all the objects to remove in a second collection, you may use ArrayList#removeAll(Collection)
Removes from this list all of its elements that are contained in the
specified collection.
Parameters:
c collection containing elements to be removed from this list
In this case, just do
A.removeAll(B);
When exiting your loop.
Addition
It calls ArrayList#batchRemove which will use a loop to remove the objects but you do not have to do it yourself.
What is the simplest way to just iterate over ArrayList rows values?
For example I have two ArrayList:
ArrayList<Object> main = new ArrayList<Object>();
ArrayList<Object> row = new ArrayList<Object>();
I use two fors to add values into main. First I add row, then when row iterations end, I add it to main, and then repeat for another row etc. For example:
for(int i=0; i < somearray.length; i++){
for(int j=0; j < somearray2.length; j++){
if(somearray2[j] == true)
row.add(somearray2[j]);
}
main.add(row);
}
So now I get ArrayList filled with rows like I need. But later I need to iterate over rows values, not just rows themselves from main ArrayList. How can I do that?
As I only see the method:
main.get(index), which let's me get a row, but nothing more.
So, based on your description, main is not a list of Objects, but a list of lists. So it should be declared as
List<List<Object>> main = new ArrayList<>();
The iteration now becomes obvious:
for (List<Object> row : main) {
for (Object element : row) {
// do what you want here
}
}
This has the additional advantage of making your code type-safe: you won't be able to add, inadvertently, anything other than a List<Object> inside the main list.
Yes then access them as: ((ArrayList<Object>)main.get(index)).get(index2);. But if you want all of your row element to be added to main array, you can make use of:
Collections.addAll(main, row.toArray());
I have one String array and one List<String>. What I want to do is to use the variable with a larger size and use that as the basis of the values removal of the smaller variable. I also want to get the values of the larger sized variable not present in the other. Note that the reason why the two variables differ on datatype is because the String[] group variable is a checkbox group from a jsp page and the List<String> existingGroup is a ResultSet from the database. For example:
String[] group contains:
Apple
Banana
Juice
Beef
List<String> existingGroup contains:
Apple
Beef
Lasagna
Flower
Lychee
And since the size of the two variables vary, it should still correctly remove the values.
What I have so far is
if(groupId.length >= existingGroup.size()) {
for(int i = 0; i < groupId.length; i++) {
if(! existingGroup.contains(groupId[i])) {
if(existingGroup.get(existingGroup.indexOf(groupId[i])) != null) {
// I'm unsure if I'm doing this right
}
}
}
} else {
for(int i = 0; i < existingGroup.size(); i++) {
// ??
}
}
Thanks.
Ok, I would start with converting your array into the List too. So do
List<String> input = Arrays.asList(array);
//now you can do intersections
input.retainAll(existingGroup); //only common elements were left in input
Or, if you want elements which are not common, just do
existingGroup.removeAll(input); //only elements which were not in input left
input.removeAll(existingGroup); //only elements which were not in existingGroup left
Choice is yours:-)
You can use the methods the List interface provides.
list.removeAll(Arrays.asList(array)); // Differences removed
or
list.retainAll(Arrays.asList(array)); // Same elements retained
based on your needs.
I have a bunch of indexes and I want to remove elements at these indexes from an ArrayList. I can't do a simple sequence of remove()s because the elements are shifted after each removal. How do I solve this?
To remove elements at indexes:
Collections.sort(indexes, Collections.reverseOrder());
for (int i : indexes)
strs.remove(i);
Or, using the Stream API from Java 8:
indexes.sort(Comparator.reverseOrder());
indexes.stream().mapToInt(i -> i).forEach(l::remove);
Sort the indices in descending order and then remove them one by one. If you do that, there's no way a remove will affect any indices that you later want to remove.
How you sort them will depend on the collection you are using to store the indices. If it's a list, you can do this:
List<Integer> indices;
Collections.sort(indices, new Comparator<Integer>() {
public int compare(Integer a, Integer b) {
//todo: handle null
return b.compareTo(a);
}
}
Edit
#aioobe found the helper that I failed to find. Instead of the above, you can use
Collections.sort(indices, Collections.reverseOrder());
I came here for removing elements in specific range (i.e., all elements between 2 indexes), and found this:
list.subList(indexStart, indexEnd).clear()
You can remove the elements starting from the largest index downwards, or if you have references to the objects you wish to remove, you can use the removeAll method.
you might want to use the subList method with the range of index you would like to remove and
then call clear() on it.
(pay attention that the second parameter is exclusive - for example in this case, I pass 2 meaning only index 0 and 1 will be removed.):
public static void main(String[] args) {
ArrayList<String> animals = new ArrayList<String>();
animals.add("cow");
animals.add("dog");
animals.add("chicken");
animals.add("cat");
animals.subList(0, 2).clear();
for(String s : animals)
System.out.println(s);
}
}
the result will be:
chicken
cat
You can remove the indexes in reverse order. If the indexes are in order like 1,2,3 you can do removeRange(1, 3).
I think nanda was the correct answer.
List<T> toRemove = new LinkedList<T>();
for (T t : masterList) {
if (t.shouldRemove()) {
toRemove.add(t);
}
}
masterList.removeAll(toRemove);
You can sort the indices as many said, or you can use an iterator and call remove()
List<String> list = new ArrayList<String>();
list.add("0");
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
List<Integer> indexes = new ArrayList<Integer>();
indexes.add(2);
indexes.add(5);
indexes.add(3);
int cpt = 0;
Iterator<String> it = list.iterator();
while(it.hasNext()){
it.next();
if(indexes.contains(cpt)){
it.remove();
}
cpt++;
}
it depends what you need, but the sort will be faster in most cases
Use guava! The method you are looking is Iterators.removeAll(Iterator removeFrom, Collection elementsToRemove)
If you have really many elements to remove (and a long list), it may be faster to iterate over the list and add all elements who are not to be removed to a new list, since each remove()-step in a array-list copies all elements after the removed one by one. In this case, if you index list is not already sorted (and you can iterate over it parallel to the main list), you may want to use a HashSet or BitSet or some similar O(1)-access-structure for the contains() check:
/**
* creates a new List containing all elements of {#code original},
* apart from those with an index in {#code indices}.
* Neither the original list nor the indices collection is changed.
* #return a new list containing only the remaining elements.
*/
public <X> List<X> removeElements(List<X> original, Collection<Integer> indices) {
// wrap for faster access.
indices = new HashSet<Integer>(indices);
List<X> output = new ArrayList<X>();
int len = original.size();
for(int i = 0; i < len; i++) {
if(!indices.contains(i)) {
output.add(original.get(i));
}
}
return output;
}
order your list of indexes, like this
if 2,12,9,7,3 order desc to 12,9,7,3,2
and then do this
for(var i = 0; i < indexes.length; i++)
{
source_array.remove(indexes[0]);
}
this should resolve your problem.
If the elements you wish to remove are all grouped together, you can do a subList(start, end).clear() operation.
If the elements you wish to remove are scattered, it may be better to create a new ArrayList, add only the elements you wish to include, and then copy back into the original list.
Edit: I realize now this was not a question of performance but of logic.
If you want to remove positions X to the Size
//a is the ArrayList
a=(ArrayList)a.sublist(0,X-1);
Assuming your indexes array is sorted (eg: 1, 3, 19, 29), you can do this:
for (int i = 0; i < indexes.size(); i++){
originalArray.remove(indexes.get(i) - i);
}
A more efficient method that I guess I have not seen above is creating a new Arraylist and selecting which indices survive by copying them to the new array. And finally reassign the reference.
I ended up here for a similar query and #aioobe's answer helped me figure out the solution.
However, if you are populating the list of indices to delete yourself, might want to consider using this:
indices.add(0, i);
This will eliminate the need for (the costly) reverse-sorting of the list before iterating over it, while removing elements from the main ArrayList.