简体   繁体   中英

Sort a list with element still in first position

I have a String list:

List<String> listString  = new ArrayList<String>();
listString.add("faq");
listString.add("general");
listString.add("contact");

I do some processing on the list and I want to sort this list but I want "general" to always end up in first position. Thx ;)

I like @Petar's approach, but another approach would be to sort it using a custom Comparator that always said that "general" was before whatever it was being compared to.

Collections.sort(list, new Comparator<String>()
  {
     int compare(String o1, String o2)
     {
         if (o1.equals(o2)) // update to make it stable
           return 0;
         if (o1.equals("general"))
           return -1;
         if (o2.equals("general"))
           return 1;
         return o1.compareTo(o2);
     }
});

Do Collections.sort on its subList instead.

    List<String> list = new ArrayList<String>(
        Arrays.asList("Zzz...", "Two", "One", "Three")
    );
    Collections.sort(list.subList(1, list.size()));
    System.out.println(list);
    // "[Zzz..., One, Three, Two]"

API links

  • subList(int fromIndex, int toIndex)
    • Returns a view of the portion of this list between the specified fromIndex , inclusive, and toIndex , exclusive. The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa. The returned list supports all of the optional list operations supported by this list.

If the special element is not at index 0, then simply put it there before you sort it as follows:

    List<String> list = new ArrayList<String>(
        Arrays.asList("Four", "Five", "Zzz...", "Two", "One", "Three")
    );
    Collections.swap(list, list.indexOf("Zzz..."), 0);
    Collections.sort(list.subList(1, list.size()));
    System.out.println(list);
    // "[Zzz..., Five, Four, One, Three, Two]"

API links

对列表进行排序而不在其中包含“常规”,然后将其添加到开头。

You can use the following code snippet but it might have perfomance/memory problems for the very big lists.

public static List<String> sortSpecial(List<String> list, final String alwaysOnTopItem) {
    list.remove(alwaysOnTopItem);
    Collections.sort(list);

    List<String> result = new ArrayList<String>(list.size() + 1);
    result.add(alwaysOnTopItem);
    result.addAll(list);

    return result;
}

public static void main(String[] args) {
    List<String> listString = new ArrayList<String>();
    listString.add("faq");
    listString.add("general");
    listString.add("contact");
    String alwaysOnTopItem = "general";
    List<String> sortedList = sortSpecial(listString, alwaysOnTopItem);
    System.out.println(sortedList);
}

Nice! Question. If we want to fix the positions for the first and last elements then we can enhance the @Paul Tomblin's approach as like below one. Please copy the code and try it.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class CustomComparatorToFixedPosition {

  public static void main(String[] args) {
    List<Emp> empNames = new ArrayList<>();
    empNames.add(new Emp("name1"));
    empNames.add(new Emp("LastName"));
    empNames.add(new Emp("name2"));
    empNames.add(new Emp("FirstName"));
    empNames.add(new Emp("name3"));
    getSortedName(empNames).stream().forEach(emp -> System.out.println(emp.getName()));
  }

  public static List<Emp> getSortedName(List<Emp> empNames) {
    String first = "FirstName";
    String last = "LastName";
    Collections.sort(empNames, new Comparator<Emp>() {
      public int compare(Emp o1, Emp o2) {
        if (o1.getName().equalsIgnoreCase(first) || o2.getName().equalsIgnoreCase(last))
          return -1;
        if (o2.getName().equalsIgnoreCase(first) || o1.getName().equalsIgnoreCase(last))
          return 1;
        return o1.getName().compareTo(o2.getName());
      }
    });
    return empNames;
  }
}

class Emp {

  private String name;

  Emp(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM