Want to order chats in ArrayList by timestamp using Comparator, but it's not working and I don't know why

Viewed 213

I have implemented a chat function in my app and it's working fine, only problem is that now I want the chats to be ordered by timestamp, so that the newest ones come first and the oldest come last. I have tried doing so using Comparator, but for some reason it's not working and I am not sure how to fix it.

Below you have my MessageActivity where I save the chats to the Firebase, and my ChatFragment that contains the ArrayList for the chats. The chats are appearing there, but I can't get them by any means to rearrange themselves and get in order by Timestamp.

Someone mind telling me how to fix this?

enter image description here

ChatFragment

public class ChatsFragment extends Fragment {

    private RecyclerView mRecyclerView;
    private UserAdapterChat mUserAdapterChat;
    private List<User> mUsers;
    private List<Chatlist> mChatList;
    private FirebaseUser mFirebaseUser;
    private TextView mNoMessages;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_chats, container, false);

        mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
        mNoMessages = v.findViewById(R.id.no_messages);

        mRecyclerView = v.findViewById(R.id.recycler_view);
        mRecyclerView.setHasFixedSize(true);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
        mRecyclerView.setLayoutManager(linearLayoutManager);

        mChatList = new ArrayList<>();
        mUserAdapterChat = new UserAdapterChat(getContext(), mUsers, false);
        mRecyclerView.setAdapter(mUserAdapterChat);

        mUsers = new ArrayList<>();

        EditText search_users = v.findViewById(R.id.search_bar);
        search_users.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                searchUsers(s.toString().toLowerCase());
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Chatlist").child(mFirebaseUser.getUid());
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                Log.d("CHAT", dataSnapshot.toString());
                mChatList.clear();
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    Chatlist chatlist = snapshot.getValue(Chatlist.class);
                    mChatList.add(chatlist);
                }

                if (mChatList.size() == 0) {
                    mNoMessages.setVisibility(View.VISIBLE);
                } else {
                    mNoMessages.setVisibility(View.GONE);
                    chatList();
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

        Task<InstanceIdResult> task = FirebaseInstanceId.getInstance().getInstanceId();
        task.addOnCompleteListener(task1 -> {
            if (task1.isSuccessful()) {
                String token = task1.getResult().getToken();
                updateToken(token);
            } else {
                Exception exception = task1.getException();
                Log.d("TOKEN", exception.getMessage());
            }
        });

        return v;
    }

    private void updateToken(String token) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Tokens");
        Token token1 = new Token(token);
        reference.child(mFirebaseUser.getUid()).setValue(token1);
    }

    private void searchUsers(String s) {
        Query query = FirebaseDatabase.getInstance().getReference("Users").orderByChild("username").startAt(s).endAt(s + "\uf8ff");
        query.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                mUsers.clear();
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    User user = snapshot.getValue(User.class);
                    if (s.length() == 0) {
                        mUsers.clear();
                    } else {
                        if (user != null) {
                            if (!user.getId().equals(mFirebaseUser.getUid())) {
                                mUsers.add(user);
                                mNoMessages.setVisibility(View.GONE);
                            }
                        }
                    }
                }

                mUserAdapterChat = new UserAdapterChat(getContext(), mUsers, false);
                mUserAdapterChat.notifyDataSetChanged();
                mRecyclerView.setAdapter(mUserAdapterChat);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }

    private void chatList() {
        mUsers = new ArrayList<>(mChatList.size());
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
        reference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                mUsers.clear();
                Collections.sort(mChatList, ChatsFragment.this::compare);
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    User user = snapshot.getValue(User.class);
                    for (int i = 0; i < mChatList.size(); i++) {
                        if (mFirebaseUser != null && user != null) {
                            if (!user.getId().equals(mFirebaseUser.getUid()) && user.getId().equals(mChatList.get(i).receiver)) {
                                ensureSize((ArrayList<?>) mUsers, mChatList.size());
                                mUsers.set(i, user);
                            }
                        }
                    }
                }

                mUserAdapterChat = new UserAdapterChat(getContext(), mUsers, true);
                mUserAdapterChat.notifyDataSetChanged();
                mRecyclerView.setAdapter(mUserAdapterChat);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }

    public static void ensureSize(ArrayList<?> list, int size) {
        list.ensureCapacity(size);
        while (list.size() < size) {
            list.add(null);
        }
    }

    public int compare(Chatlist o1, Chatlist o2) {
        return o1.getTimestamp() < o2.getTimestamp() ? 1 : (o1.getTimestamp() == o2.getTimestamp() ? 0 : -1);
    }
}





        
    
2 Answers

You are sorting collection in ascending order by using Long.compare(). For showing latest chat you need to change the compare method as

public int compare(Chatlist o1, Chatlist o2) {
                    return o1.getTimestamp() < o2.getTimestamp() ? 1 : 
                   (o1.getTimestamp == o2.getTimestamp() ? 0 : -1);
}

You can simply use Java8 feature to compare the element as below:

List<ChatList> unique = list.stream().collect(collectingAndThen(toCollection(() -> new TreeSet<>(comparing(ChatList::getTimestamp))),ArrayList::new));
unique.forEach((k) -> System.out.println(k.getTimestamp()));
Related