Я хочу создать приложение чата с Android Studio, и когда я хочу отображать пользователей в своем приложении, приложение разбилось, и мой код приведен ниже:
private void readChats()
{
mUsers = new ArrayList<>();
reference = FirebaseDatabase.getInstance().getReference("Users");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
{
mUsers.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren())
{
User user = snapshot.getValue(User.class);
for (String id : userList){
assert user != null;
if (user.getId().equals(id)) {
if (mUsers.size() != 0) {
for (User user1 : mUsers) {
if (!user.getId().equals(user1.getId())) {
mUsers.add(user);
}
}
}else {
mUsers.add(user);
}
}
}
}
userAdapter = new UserAdapter(getContext(), mUsers);
recyclerView.setAdapter(userAdapter);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError)
{
}
});
}
и моя ошибка ниже:
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at com.example.mahdi.chatapp.Fragments.ChatsFragment$2.onDataChange(ChatsFragment.java:101)
и ошибка из этой строки:
for (User user1 : mUsers)
Я не могу исправить эту ошибку, пожалуйста, помогите мне:
Вы не можете изменить этот список ("mUsers") в цикле, потому что цикл использует количество элементов для ограничения. Если вы делаете временную переменную или используете этот код:
for (User user : new ArrayList< User >(mUsers)) {
if (!user.getId().equals(user1.getId())) {
}
}
Я надеюсь, что это полезно
Если вы используете простой цикл for вместо расширенного цикла for, ваша проблема решена.
if (mUsers.size() != 0) {
for (User user1 : mUsers) {
if (!user.getId().equals(user1.getId())) {
mUsers.add(user);
}
}
}else {
mUsers.add(user);
}
Помимо ConcurrentModificationException (который происходит от mUsers.add(user) внутри цикла над mUsers), я не думаю, что это та логика, которую вы имеете в виду. Это добавит user в список N раз, где N — количество пользователей в списке с разными идентификаторами.
Я подозреваю, что вы можете захотеть что-то вроде:
if (mUsers.stream().noneMatch(u -> user.getId().equals(u.getId())) {
mUsers.add(user);
}
который добавляет user один раз, если нет другого пользователя с этим идентификатором.
Вы также можете рассмотреть возможность использования Map<String, User>, где ключ — это идентификатор пользователя. Затем вы можете использовать:
map.computeIfAbsent(user.getId(), k -> user);
Я тоже столкнулся с этой проблемой. Лучше вы можете использовать приведенный ниже фрагмент кода, который гарантирует, что только один пользователь был добавлен в ChatFragment.
reference=FirebaseDatabase.getInstance().getReference("Users");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mUsers.clear();
for(DataSnapshot snapshot:dataSnapshot.getChildren()){
User user=snapshot.getValue(User.class);
//Display 1 user from chat
for (String id:usersList){
assert user != null;
if (user.getId().equals(id)){
if (mUsers.size()!=0){
int flag=0;
for(User u : mUsers) {
if (user.getId().equals(u.getId())) {
flag = 1;
break;
}
}
if (flag==0)
mUsers.add(user);
}else{
mUsers.add(user);
}
}
}
}
userAdapter=new UserAdapter(getContext(),mUsers,true);
recyclerView.setAdapter(userAdapter);
Спасибо