0

I want to sort this

LG Electronics  1.jpg   
Apple   2.JPG   
Apple   3.JPG

As

Apple   2.JPG   
Apple   3.JPG
LG Electronics  1.jpg   

Here is my code //rows is 2d

ArrayList<String[]> rows = new ArrayList<>();
for(int i=0;i<images.length;i++){
    com.drew.metadata.Metadata metadata = ImageMetadataReader.readMetadata(images[i]);
    for (com.drew.metadata.Directory directory : metadata.getDirectories()) {
        for (Tag tag : directory.getTags()) {
            //System.out.println(tag.toString());
            if(tag.toString().contains("[Exif IFD0] Make")){
                rows.add(new String[]{tag.getDescription(),images[i].toString()});
            }
        }
    }
}

I have implemented Collections.sort(rows); but nothing works for me. I even tried

Collections.sort(rows, new Comparator<ArrayList<String>>() {
    @Override
    public int compare(ArrayList<String> o1, ArrayList<String> o2) {
    return o1.get(0).compareTo(o2.get(0));
    }
    });

But it also doesn't works for me. I got this error that no suitable method found for sort(arraylist

azro
  • 35,213
  • 7
  • 25
  • 55
  • rows is a List. So its elements are String[]. So, to compare them, you need a Comparator. – JB Nizet Nov 14 '18 at 22:53
  • Can you help me doing that I'm really stuck implementing everything. Seems nothing works for me.. – Muhammad Irfan Nov 14 '18 at 22:59
  • Check this link https://stackoverflow.com/questions/21664875/java-generics-array-of-the-generic-type it mentions an item from Josh Bloch's book Effective Java... where he clearly mentions never mix Generics with Array. That's first thing... In general Josh suggests that try to keep the things simple in your programming and then solutions will just come simple as well... – Ketan Nov 14 '18 at 23:38

1 Answers1

2

I would advise against using a model such as ArrayList<String[]> rows in your case because it really doesn't tell much about what the list is holding -- and it makes implementing the comparison clunky.

Instead, you could model the metadata as a Java class:

public class Metadata {

  private final String description;
  private final String imageName;

  public Metadata(String description, String imageName) {
    this.description = description;
    this.imageName = imageName;
  }
  public String getDescription() {return description;}
  public String getImageName() {return imageName;}

  @Override
  public String toString() {
    return description + " " + imageName;
  }
}

Now, you can have a List<Metadata> rows = new ArrayList<>(); which you populate inside the loop only changing this part:

rows.add(new String[]{tag.getDescription(),images[i].toString()});

into this

rows.add(new Metadata(tag.getDescription(), images[i].toString());

And finally, you can sort with a proper Comparator using

Collections.sort(rows, Comparator
                        .comparing(Metadata::getDescription)
                        .thenComparing(Metadata::getImageName));
Mick Mnemonic
  • 7,403
  • 2
  • 23
  • 27
  • Glad to help. If you think this answers your question, you can also choose to accept the answer. – Mick Mnemonic Nov 14 '18 at 23:38
  • Now what if I want to get the original values after sorting like: Apple 2.JPG Apple 3.JPG LG Electronics 1.jpg Now when i print `rows` after sorting all i get is output like` sorting.Data@387f0054` How can I can get specific values like `imageName` – Muhammad Irfan Nov 14 '18 at 23:40
  • I modified the `Metadata` class to include a `toString()` implementation which should take care of the problem (and you can change as you wish). I think there is a checkbox you can tick in the UI somewhere for accepting the answer. – Mick Mnemonic Nov 14 '18 at 23:44
  • done brother that was really helpful... I was stuck here but i think grateful to you – Muhammad Irfan Nov 14 '18 at 23:48