java.lang.Long无法转换为java.lang.Integer

4

我想从数据库(Firebase)中读取一个名为map的映射并将其与另一个映射motcle进行比较,如果找到重复的键,则会增加map中该键的值,但是我遇到了一个ClassCastException异常。

以下是代码:

public void addMotcle(final Map motcle, String Userid)
{
    mDatabase = FirebaseDatabase.getInstance().getReference("User");
    DatabaseReference user = mDatabase.child(Userid);
    final DatabaseReference keylist = user.child("motcle");
    keylist.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if(dataSnapshot.exists())
            {   
                //I tried to put the map in another map and change it but 
                //It is still the same error
                Map<String,Integer> map = (Map) dataSnapshot.getValue();
                Map<String,Integer>Hmap= new HashMap<>();
                Hmap.putAll(map);
                //if there is duplicate we incremente les mots clé
                for (Object key : motcle.keySet()) {
                    if (Hmap.containsKey(key)) {
                        Hmap.put((String)key,((Integer) Hmap.get(key))+1);
                    }
                    else
                    {
                        Hmap.put((String) key,1);
                    }
                }
               keylist.setValue(Hmap);

            }
            else
            {
             keylist.setValue(motcle);

            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });



}

这是我想要在Firebase上写入的值:Data

错误出现在这一行:map.put((String)key,map.get(key)+1);

如果我将map声明为Map<String,Integer>,为什么不能在值中写入一个Integer


你正在处理整数包装类(Integer wrapper class),而不是原始的int类型,因此它并不能这样做。进行类型转换,然后再次使用 new Integer(result_int) - Red Boy
你能试试 map.put((String) key, ((Integer) map.get(key)) + 1); 吗? - Youcef LAIDANI
1
我不太了解Firebase,但是快速查看文档似乎表明您关于“dataSnapshot.getValue()”返回值的假设是错误的。根据此链接,该方法永远不会返回“Map <String,Integer>”,也不会返回“Integer”。 - Radiodef
即使执行 map.put((String)key,((Integer) map.get(key))+1);,仍然会出现相同的错误。 - Anis Kaloun
2个回答

2
当你执行Map<String,Integer> map = (Map) dataSnapshot.getValue();时,你保证了map是一个Map,但不保证它是一个Map<String, Integer>。由于泛型在运行时被擦除且不可用,只要dataSnapshot.getValue()是某种类型的Map,这个转换就会成功。
因为你将Hmap声明为Map<String,Integer>,当你从map中获取值时,它会尝试将其转换为Integer,但实际上没有任何事情可以提前保证它将是一个整数。因此,如果该值实际上是一个Long,它将尝试将该Long转换为Integer并失败(因为Long不扩展Integer,并且扩展操作不适用于装箱类型)。
你需要找出dataSnapshot.getValue()的值的实际类型,并将其转换为正确类型的Map以避免此错误。
更多详情请参见:Weird problem about Java Generics operation

dataSnapshot.getValue 的实际值类型是 Map<String,Integer>,因此我将其放入一个 <String,Integer> 的映射中。 - Anis Kaloun
@Anis Kaloun 你怎么知道那是什么类型?map.get(key).getClass()的结果是什么? - VeeArr
我还没有尝试过,现在我要试一下。如果我在数据库中写入一个 Map<String,Integer> 并使用 setValue,然后想要读取它,它不能保证仍然是一个 Map<String,Integer> 吗? - Anis Kaloun

-1

这是因为keylist是一个final变量,你不能改变它的值,所以你只能像这样初始化它:-

DatabaseReference keylist = user.child("motcle");

我尝试创建另一个Map并复制内容,但仍然出现相同的错误。Map<String,Integer> map = (Map) dataSnapshot.getValue(); Map<String,Integer>Hmap= new HashMap<>(); Hmap.putAll(map); //如果有重复,我们增加关键字 for (Object key : motcle.keySet()) { if (Hmap.containsKey(key)) { Hmap.put((String)key,((Integer) Hmap.get(key))+1); } - Anis Kaloun
一个变量被声明为“final”并不意味着不能对该变量执行可变操作,它只是阻止你将变量重新赋值为引用不同的对象。 - VeeArr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接