Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: How to remove objects from an Array depending on the condition?

Tags:

java

iteration

I have an array of Objects (file list excatly). How to iterate through this array and delete some Objects (in Java) - depending on the condition ?

File[] files = file.listFiles();
for(File f: files) {
   if(someCondition) {
       // remove
   }
}
like image 974
marioosh Avatar asked Jul 11 '11 07:07

marioosh


4 Answers

I think the best Java way to tackle your problem is to convert your array into a list and use an iterator which allows you to remove objects:

List<File> files = new ArrayList<File>(Arrays.asList(file.listFiles()));
Iterator<File> iterator = files.iterator();
while(iterator.hasNext()){
    File currentFile = iterator.next();
    if(someCondition){
        iterator.remove();
    }
    // other operations
}

You can even convert it again into an array if necessary -even though handling a list is probably more convenient ...:

File[] filesArray = files.toArray();
like image 157
Jean Logeart Avatar answered Nov 15 '22 15:11

Jean Logeart


You may be better off giving FilenameFilter to listFiles and apply condition there. See File documentation http://download.oracle.com/javase/6/docs/api/java/io/File.html

like image 38
Alex Gitelman Avatar answered Nov 15 '22 16:11

Alex Gitelman


We can't delete elements and resize the arrays in one step/operation. Arrays can't be resized.

Either use a List or (1) flag the elements you want to delete and (2) write the elements you want to keep, to a new array.

Here's a solution if you want to continue with arrays (List is much easier):

private File[] filter(File[] files) {
  boolean[] deleteFlags = new boolean[files.length];
  int deleteCounter = 0;

  // collection
  for (int i = 0; i < files.length; i++) {
    if (deleteConditionIsTrue()) {
       deleteFlags[i] = true;
       deleteCounter++;
    }
  }

  // create result
  File[] result = new File[files.length-deleteCounter];
  int gapCounter = 0;
  for (int i = 0; i < deleteFlags.length; i++) {
    if (deleteFlags[i]) {
      gapCounter++; // skip entry, has been filtered/deleted
    } else {
      result[i-gapCounter] = files[i];
    }          
  }

  return result;
}
like image 31
Andreas Dolk Avatar answered Nov 15 '22 15:11

Andreas Dolk


JB Nizet has it exactly right:

  1. You can't "delete" elements from an array

  2. You can set elements to "null". This effectively deletes them (in a C kind of way), but it requires extra logic so you don't accidentally try to reference a null element.

  3. All things being equal, you're probably better off with a List<>, which does allow you to insert and delete elements.

PS: If you know a priori what elements you don't want, the FileFilter idea is an excellent way to keep from getting them in the first place.

like image 21
paulsm4 Avatar answered Nov 15 '22 15:11

paulsm4