Compare method only called when 3 or more objects exist

114 views Asked by At

I'm trying to understand while the compare method is called when and only when 3 or more Jpeg objects have been created.

The goal is to sort Jpeg timestamps in ascending order before adding them to a table.

2 Objects not following sequence

3 Objects in ascending order

private class ExtractJpegMetadata extends Task {

    private File[] selectedJpegs;
    private Jpeg jpeg;

    public ExtractJpegMetadata(Application application, File[] selectedJpegs) {
        super(application);
        this.selectedJpegs = selectedJpegs;
    }

    @Override
    protected Object doInBackground() throws Exception {
        setMessage("Extracting jpeg metadata.");

        for (File file : selectedJpegs) {
            com.drew.metadata.Metadata metadata = ImageMetadataReader.readMetadata(file);
            // obtain the Exif directory
            ExifSubIFDDirectory directory = metadata.getDirectory(ExifSubIFDDirectory.class);
            jpeg = new Jpeg();
            jpeg.setImgTimestamp(directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL));

            Collections.sort(jpegList, jpeg);
            jpegList.add(jpeg);

        }

        jpegAlbum.setJpegAlbum(jpegList);         
        return null;
    }

    @Override
    protected void succeeded(Object result) {
        setMessage("Finished extracting jpeg metadata.");
        updateTableNeeded(true);
    }
}

Jpeg class

@XmlRootElement
public class Jpeg implements Comparator<Jpeg> {

private Date imgTimestamp;

public Jpeg() {
}

public Jpeg(Date imgTimestamp) {
    this.imgTimestamp = imgTimestamp;
}

public Date getImgTimestamp() {
    return imgTimestamp;
}

@XmlElement
public void setImgTimestamp(Date imgTimestamp) {
    this.imgTimestamp = imgTimestamp;
}

public int compare(Jpeg t, Jpeg t1) {
    return t.getImgTimestamp().compareTo(t1.getImgTimestamp());
}
}
3

There are 3 answers

0
JB Nizet On BEST ANSWER

At the firt iteration, the list is empty, and you sort it. There's nothing to compare. Then you add an element to the list.

At the second iteration, the list contains a single element, and you sort it. There's still nothing to compare. Then you add an element to the list.

At the third iteration, there are two elements in the list, and you sort it. So the first element is compared to the second element. Then you add an element to the list.

I don't understand what you're trying to achieve, but sorting the list at each iteration is useless. You'd better add all the elements, and when that's done, then sort the list. Likewise, reconstructing a new comparator at each iteration is also useless. And since this comparator is only used inside a single method, and is not really part of the state of your task, there's no reason to make it an instance variable either.

0
Kuba Spatny On

Try first adding the element to your Collection and then sort:

jpegList.add(jpeg);
Collections.sort(jpegList, jpeg);

EDIT: Also I noticed that you have the sorting in iteration, I would suggest to add all the images first and THEN sort:

for (File file : selectedJpegs) {
     jpegList.add(jpeg);
}

Collections.sort(jpegList, jpeg);
0
Prabhakaran Ramaswamy On

move out your Collections.sort(jpegList, jpeg); from the for loop

change

   for (File file : selectedJpegs) {
        com.drew.metadata.Metadata metadata = ImageMetadataReader.readMetadata(file);
        // obtain the Exif directory
        ExifSubIFDDirectory directory = metadata.getDirectory(ExifSubIFDDirectory.class);
        jpeg = new Jpeg();            jpeg.setImgTimestamp(directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL));
        Collections.sort(jpegList, jpeg);  
                 |
                 Problem is here (jpegList is sorted here)                          

        jpegList.add(jpeg);      
             |
             adding element to sorted list (the jpeg added at last)
   }

to

 for (File file : selectedJpegs) {
        com.drew.metadata.Metadata metadata = ImageMetadataReader.readMetadata(file);
        // obtain the Exif directory
        ExifSubIFDDirectory directory = metadata.getDirectory(ExifSubIFDDirectory.class);
        jpeg = new Jpeg();            jpeg.setImgTimestamp(directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL));
        jpegList.add(jpeg);    
 }
 Collections.sort(jpegList, jpeg);