【问题标题】:Android/Java how to efficiently use multiple comparator in an ArrayListAndroid / Java如何在ArrayList中有效地使用多个比较器
【发布时间】:2014-06-17 13:17:45
【问题描述】:

我有一个名为 FriendJava

public class Friend {   
    public String friendsUserName;
    public boolean isFavorite;
    public boolean isFriend;
}

我从包含此类FriendJsonArray 的服务器获得Json 文件。我使用Gson 类来解析Json 并将其映射到ArrayList<Friend>。我必须按以下方式对数组进行排序

  1. 顶级元素是Friend,分别是isFavoriteisFriend
  2. 然后ArrayList 包含剩余的Friend,他们只是isFriend
  3. 最后ArrayList 包含Friend 其中isFriendFalse

所以我可以使用ComparatorChain中描述的方法

或者我可以使用以下方式正确排序ArrayList<Friend>

 public ArrayList<Friend> friendsList;
 public void sortArrayList() {
    ArrayList<Friend> favoriteList = new ArrayList<Friend>();
    ArrayList<Friend> friendOnlyList = new ArrayList<Friend>();
    ArrayList<Friend> nonFriendList = new ArrayList<Friend>();

    for (int length = friendsList.size(), i = length - 1; i >= 0; i--) {
        Friend friend = friendsList.get(i);
        if (friend.isFriend) {
            if (friend.isFavorite) {
                favoriteList.add(friend);
            } else {
                friendOnlyList.add(friend);
            }
        } else {
            nonFriendList.add(friend);
        }
        friendsList.remove(i);
    }
    addAllAndClear(favoriteList);
    favoriteList = null;

    addAllAndClear(friendOnlyList);
    friendOnlyList = null;
    addAllAndClear(nonFriendList);
    nonFriendList = null;

}

public void addAllAndClear(ArrayList<Friend> updatedList) {
    Collections.sort(updatedList, nameComparator);
    friendsList.addAll(updatedList);
    updatedList.clear();
    updatedList = null;

}

    Comparator<Friend> nameComparator = new Comparator<FriendListResponse.Friend>() {
    @Override
    public int compare(Friend lhs, Friend rhs) {
        return lhs.friendsUserName.compareTo(rhs.friendsUserName);
    };
};

Efficiency 明智的是我应该遵循ComparatorChain 还是我自己的方法。我正在为Android 平台开发这个,所以Memory ManagementEfficiency 是最重要的。 附言我不擅长使用工具比较Efficiency

【问题讨论】:

  • 其他发帖者已经给出了潜在的解决方案,但是在优化性能时可以参考的一个很好的资源是 Android 文档中提供的 Performance Tips article

标签: java android sorting arraylist


【解决方案1】:

尝试以下比较器:

Comparator<Friend> favoriteComparator = new Comparator<FriendListResponse.Friend>() {
    @Override
    public int compare(Friend lhs, Friend rhs) {
        int i=0,j=0;
        if(lhs.isFavorite()&&lhs.isFriend())
           i++;
        if(lhs.isFriend())
           i++;
        if(rhs.isFavorite()&&rhs.isFriend())
           j++;
        if(rhs.isFriend())
           j++; 
        return i-j;
    };
};

排序时:

Collections.sort(friendsList,favoriteComparator);

【讨论】:

  • 感谢您的回答,它就像一个魅力。还有一件事,因为我希望List 包含Friend,他同时是isFavoriteisFriend 在@ 的顶部987654327@,后面是Friend,他是isFriend,其余不是朋友。所以我需要return j-i而不是return i-j
  • 是否有可能找到indexFriend 性质发生变化。例如A,BFriend 是最喜欢和最喜欢的人,C,D,EFriend 谁是唯一的人,F,G 不是最喜欢的人。所以,变化的indices0 2 5。我可以从排序列表中轻松完成,但是否可以从上方完成 comparator。意思是,排序和保持更改 indices 可以同时完成,也可以不同时完成。谢谢
  • 我不认为这个比较器可以用来实现这一点。您应该简单地在排序列表上应用 for loom 并找到索引。
  • 谢谢。我一定会使用for loop 来实现sorted list
【解决方案2】:

在你的类Friend中实现Comparable接口,然后使用Collections.sort()

或者正如@vipul mittal 建议的那样

比较器可能看起来像

Comparator<Friend> favoriteComparator = new Comparator<FriendListResponse.Friend>() {
    @Override
    public int compare(Friend lhs, Friend rhs) {
        int i=0,j=0;
        if(lhs.isFavorite() && lhs.isFriend())
           i++;
        if(lhs.isFriend())
           i++;
        if(rhs.isFavorite() && rhs.isFriend())
           j++;
        if(rhs.isFriend())
           j++; 

        if (i==j) {
            return lhs.friendsUserName.compareTo(rhs.friendsUserName);
        }
        else {
            return i-j;
        }
    };
};

【讨论】:

  • 这个。 ComparatorChain 正是这样做的,只是它为您处理链接逻辑。您需要做的就是将处理 isFavourite 的逻辑放在第一位,然后将处理 isFriend 的逻辑放在最后
  • @Unlink:感谢您的回答并感谢您实施compareTo(friendUserName)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-13
相关资源
最近更新 更多