将 ArrayList<> 按字母顺序分为两部分取决于是否标记了标志

Sort ArrayList<> Alphabetically in two parts depends if flag is marked

我有一个对象列表,其中有几个成员,最重要的是 fullName 和 isSubscribed。我想按以下顺序按字母顺序排序:

  1. 首先显示 isSubscribed 标志为 true 的按字母顺序排列的对象。
  2. 之后还显示按字母顺序排序的对象,即 isSubscribed 标志为 false。

预期的联系人顺序示例:

  1. 巴里(已订阅:真)

  2. 爱立信(已订阅:真)

  3. 安迪(已订阅:false)

  4. 厨师(已订阅:false)

我调用了列表的排序方法,该方法覆盖了方法 compareTo()。对于标记为 false 的标志,我的代码按字母顺序正确排序,但是标记为 true 的标志只是放在该列表的顶部,没有按字母顺序排列。 我拥有的联系人订单示例:

  1. 爱立信(已订阅:真)

  2. 巴里(已订阅:真)

  3. 安迪(已订阅:false)

  4. 厨师(已订阅:false)

我的可比较对象的重写代码(由于某些情况(最低 sdk 级别)我不能使用 java 8,所以请不要提供 java8 解决方案):

   @Override
    public int compareTo(PersonalContact contact) {
        String fullName = getFullName() != null ? getFullName() : "";
        String contactFullName = contact.getFullName() != null ? contact.getFullName() : "";

         int c;
        PersonalContact c1 = this;
        PersonalContact c2 = contact;
        String fullNameContact1 = c1.getFullName();
        String fullNameContact2 = c2.getFullName();
        Boolean subscribedForPresenceContact1 = c1.isSubscribeForPresenceEnabled();
        Boolean subscribedForPresenceContact2 = c2.isSubscribeForPresenceEnabled();

        c = subscribedForPresenceContact1.compareTo(subscribedForPresenceContact2);

        if (subscribedForPresenceContact1) {
            return  -1;
        } else if (subscribedForPresenceContact2) {
            return 1;
        } else  if (fullName.equals(contactFullName)) {
            String id = getAndroidId() != null ? getAndroidId() : "";
            String contactId = contact.getAndroidId() != null ? contact.getAndroidId() : "";

            if (id.equals(contactId)) {
                List<ContactNumberOrAddress> noas1 = getNumbersOrAddresses();
                List<ContactNumberOrAddress> noas2 = contact.getNumbersOrAddresses();
                if (noas1.size() == noas2.size() && noas1.size() > 0) {
                    if (!noas1.containsAll(noas2) || !noas2.containsAll(noas1)) {
                        for (int i = 0; i < noas1.size(); i++) {
                            int compare = noas1.get(i).compareTo(noas2.get(i));
                            if (compare != 0) return compare;
                        }
                    }
                } else {
                    return Integer.compare(noas1.size(), noas2.size());
                }

                String org = getOrganization() != null ? getOrganization() : "";
                String contactOrg =
                        contact.getOrganization() != null ? contact.getOrganization() : "";
                return org.compareTo(contactOrg);
            }
            return id.compareTo(contactId);
        }
        return fullName.compareTo(contactFullName);
    }

可能有更好的方法,但这是我的解决方案

 static void sort(final List<PersonalContact> contacts)
    {
        final List<PersonalContact> subscribed = new ArrayList<>();
        final List<PersonalContact> unsubscribed = new ArrayList<>();
        for(final PersonalContact contact : contacts)
        {
            if(contact.isSubscribeForPresenceEnabled())
                subscribed.add(contact);
            else
                unsubscribed.add(contact);
        }

        final PersonalContactComparator personalContactComparator = new PersonalContactComparator();
        subscribed.sort(personalContactComparator);
        unsubscribed.sort(personalContactComparator);

        contacts.clear();
        contacts.addAll(subscribed);
        contacts.addAll(unsubscribed);
    }

    private static class PersonalContactComparator implements Comparator<PersonalContact>
    {

        @Override
        public int compare(final PersonalContact o1, final PersonalContact o2)
        {
            return o1.getFullName().compareTo(o2.getFullName());
        }
    }

我建议只为 Collections.sort

使用自定义比较器

喜欢

    class PersonalContactComparator implements Comparator<PersonalContact>
    {

        @Override
        public int compare(final PersonalContact o1, final PersonalContact o2)
        {
            if (o1.isSubscribeForPresenceEnabled() == o2.isSubscribeForPresenceEnabled()) {
                return o1.getFullName().compareTo(o2.getFullName());
            }

            if (o1.isSubscribeForPresenceEnabled()) {
                return 1;
            }

            return -1;
        }
    }

并将其用作Collections.sort(list, new PersonalContactComparator());

PS:这种方法类似于另一个答案,但更通用

如果我理解你可以使用以下内容:

list.sort(Comparator.comparingInt(pc -> pc.isSubscribeForPresenceEnabled() ? 0 : 1)
                    .thenComparing(PersonalContact::getFullName));

或者如果我没记错的话(我不确定atm)。布尔值是可比较的:

list.sort(Comparator.comparing(PersonalContac::isSubscribeForPresenceEnabled)
                    .reversed()
                    .thenComparing(PersonalContact::getFullName));

~比较~方法给出了左轴和右轴中任意一个的比较键,然后可以进行比较。

遗憾的是没有比较布尔值。