java sort if includes and then by abc

Viewed 105

Hey I want to sort photo by name, first I want all photos that have the word "profile" in it, and then compare the rest by ABC

Currently I'm only sorting by name

            photos
            .stream()
            .sorted(Comparator.comparing(Photo::getFileName))
            .collect(Collectors.toList());

How can I achieve that? thanks

3 Answers

Write logic to determine an ordering "priority", with lower value be higher priority, e.g.

  • 0 = contains "profile"
  • 1 = everything else

Then sort by priority first, before you sort by name.

In the following example, we use regex for a case-insensitive "contains" check, and we pre-compile it for better performance.

Pattern containsProfile = Pattern.compile("profile", Pattern.CASE_INSENSITIVE);

photos.stream()
      .sorted(Comparator.comparingInt((Photo p) -> containsProfile.matcher(p.getFileName()).find() ? 0 : 1)
                        .thenComparing(Photo::getFileName))
      .collect(Collectors.toList());

You need to write your own implementation of Comparator interface.

Since your Stream contains Photo elements, you need a Comparator that compares Photo objects.

Comparator<Photo> comparator = (Photo p1, Photo p2) -> {
    String p1Filename = p1.getFileName();
    String p2Filename = p2.getFileName();
    if (p1Filename.contains("profile") {
        if (p2Filename.contains("profile") {
            String tmp1 = p1Filename.replaceFirst("profile", "");
            String tmp2 = p2Filename.replaceFirst("profile", "");
            return tmp1.compareTo(tmp2);
        }
        else {
            return 1;
        }
    }
    else {
        if (p2Filename.contains("profile") {
            return -1;
        }
        else {
            return p1Filename.compareTo(p2Filename);
        }
    }
};

Then you just pass that Comparator to your stream operation.

photos.stream()
      .sorted(comparator)
      .collect(Collectors.toList());

You could try:

photos.stream()
      .sorted((s1, s2) -> 
      .collect(Collectors.toList());
Related