为啥我的数组列表即使在初始化后也会抛出空指针异常?

Posted

技术标签:

【中文标题】为啥我的数组列表即使在初始化后也会抛出空指针异常?【英文标题】:Why is my Array List throwing a null pointer exception even after initialisation?为什么我的数组列表即使在初始化后也会抛出空指针异常? 【发布时间】:2020-08-14 23:20:32 【问题描述】:

我正在为我的应用开发搜索功能。我为我的家庭适配器实现了 Filterable 方法。我的数组列表抛出了一个空指针异常,并且我看到了许多其他类似的问题,其中问题不是初始化数组列表。但是,我有以下代码,但我不确定它是否在正确的位置初始化。请告诉我如何纠正这个问题。谢谢。

这是我得到的错误:

我家的适配器代码如下:

package com.example.oddsynew.Home;

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.oddsynew.Modals.Job;
import com.example.oddsynew.R;
import com.squareup.picasso.Picasso;

import java.util.ArrayList;
import java.util.List;

public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder> implements Filterable 

    Context context;
    ArrayList<Job> jobs, jobsListFull;



    public HomeAdapter(Context c, ArrayList<Job> j) 
        context = c;
        jobs = j;
    

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
        return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.job_row, parent, false));
    

    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) 
        holder.recruiterName.setText(jobs.get(position).getRecruiter_name());
        holder.jobName.setText(jobs.get(position).getJob_name());
        holder.jobLocation.setText(jobs.get(position).getLocation());
        holder.jobCharge.setText(jobs.get(position).getJob_charge());
        Picasso.get().load(jobs.get(position).getProf_pic()).into(holder.profPic);

        holder.itemView.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                try 
                    Intent intent = new Intent(context, JobInfo.class);
                    intent.putExtra("recruiterName", jobs.get(holder.getAdapterPosition()).getRecruiter_name());
                    intent.putExtra("jobName", jobs.get(holder.getAdapterPosition()).getJob_name());
                    intent.putExtra("jobCharge", jobs.get(holder.getAdapterPosition()).getJob_charge());
                    intent.putExtra("jobLocation", jobs.get(holder.getAdapterPosition()).getLocation());
                    intent.putExtra("profPic", jobs.get(holder.getAdapterPosition()).getProf_pic());
                    intent.putExtra("startDate", jobs.get(holder.getAdapterPosition()).getStart_date());
                    intent.putExtra("endDate", jobs.get(holder.getAdapterPosition()).getEnd_date());
                    intent.putExtra("startTime", jobs.get(holder.getAdapterPosition()).getStart_time());
                    intent.putExtra("endTime", jobs.get(holder.getAdapterPosition()).getEnd_time());
                    intent.putExtra("jobDesc", jobs.get(holder.getAdapterPosition()).getJob_desc());
                    intent.putExtra("jobTasks", jobs.get(holder.getAdapterPosition()).getJob_tasks());
                    intent.putExtra("addPref", jobs.get(holder.getAdapterPosition()).getAdd_pref());
                    intent.putExtra("jobID", jobs.get(holder.getAdapterPosition()).getJobID());
                    context.startActivity(intent);
                 catch (Exception e) 
                    e.printStackTrace();
                
            
        );
    

    @Override
    public int getItemCount() 
        return jobs.size();
    

    @Override
    public Filter getFilter() 
        return searchFilter;
    

    private Filter searchFilter = new Filter() 
        @Override
        protected FilterResults performFiltering(CharSequence constraint) 
            ArrayList<Job> filteredList = new ArrayList<>();

            if(constraint == null || constraint.length() == 0)
                filteredList.addAll(jobsListFull);
            else
                String filterPattern = constraint.toString().toLowerCase().trim();

                for(Job job: jobsListFull)
                    if(job.getJob_name().toLowerCase().contains(filterPattern))
                        filteredList.add(job);
                    
                
            
            FilterResults results = new FilterResults();
            results.values = filteredList;

            return results;
        

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) 
            jobs.clear();
            jobs.addAll((List) results.values);
            notifyDataSetChanged();

        
    ;

    class MyViewHolder extends RecyclerView.ViewHolder 
        TextView recruiterName, jobName, jobLocation, jobCharge;
        ImageView profPic;

        public MyViewHolder(@NonNull View itemView) 
            super(itemView);
            recruiterName = itemView.findViewById(R.id.recruiterName);
            jobName = itemView.findViewById(R.id.jobName);
            jobLocation = itemView.findViewById(R.id.jobLocation);
            jobCharge = itemView.findViewById(R.id.jobCharge);
            profPic = itemView.findViewById(R.id.prof_pic);
        
    

    public HomeAdapter(ArrayList<Job> jobs) 
        this.jobs = jobs;
        jobsListFull = new ArrayList<>(jobs);
    

这是我的搜索类:

package com.example.oddsynew;

import android.os.Bundle;
import android.widget.SearchView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.oddsynew.Home.HomeAdapter;
import com.example.oddsynew.Modals.Job;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;

public class Search extends AppCompatActivity 

    DatabaseReference myRef;
    RecyclerView newJobList;
    ArrayList<Job> list;
    HomeAdapter adapter;
    SearchView searchView;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);

        newJobList = (RecyclerView) findViewById(R.id.jobRecyclerView);

        searchView = (SearchView) findViewById(R.id.search);

        try 
            newJobList.setLayoutManager(new LinearLayoutManager(Search.this));
            list = new ArrayList<Job>();

            adapter = new HomeAdapter(Search.this, list);
            newJobList.setAdapter(adapter);

            myRef = FirebaseDatabase.getInstance().getReference().child("Jobs");
            myRef.addValueEventListener(new ValueEventListener() 
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) 
                    for (DataSnapshot ds : dataSnapshot.getChildren()) 
                        Job j = ds.getValue(Job.class);
                        list.add(j);
                    
                    System.out.println(list);
                    adapter.notifyDataSetChanged();
                

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) 
                    Toast.makeText(Search.this, "Error", Toast.LENGTH_SHORT).show();
                
            );

            searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() 
                @Override
                public boolean onQueryTextSubmit(String query) 
                    return false;
                

                @Override
                public boolean onQueryTextChange(String newText) 
                    adapter.getFilter().filter(newText);
                    return false;
                
            );

         catch (Exception e) 
            e.printStackTrace();
        


    

解决方案:IntelliJ Amiya的帮助下,我想出了以下更正的代码。

 @Override
    public Filter getFilter() 
        return searchFilter;
    

    private Filter searchFilter = new Filter() 
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) 
                String charString = charSequence.toString();
                if (charString.isEmpty()) 
                    jobs = jobsListFull;
                 else 
                    ArrayList<Job> filteredList = new ArrayList<>();
                    for (Job row : jobsListFull) 


                        if (row.getJob_name().toLowerCase().contains(charString.toLowerCase())) 
                            filteredList.add(row);
                        
                    

                    jobs = filteredList;
                

                FilterResults filterResults = new FilterResults();
                filterResults.values = jobs;
                return filterResults;
            

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) 
                jobs = ((ArrayList) filterResults.values);
                notifyDataSetChanged();
            
        ;

    class MyViewHolder extends RecyclerView.ViewHolder 
        TextView recruiterName, jobName, jobLocation, jobCharge;
        ImageView profPic;

        public MyViewHolder(@NonNull View itemView) 
            super(itemView);
            recruiterName = itemView.findViewById(R.id.recruiterName);
            jobName = itemView.findViewById(R.id.jobName);
            jobLocation = itemView.findViewById(R.id.jobLocation);
            jobCharge = itemView.findViewById(R.id.jobCharge);
            profPic = itemView.findViewById(R.id.prof_pic);
        
    

【问题讨论】:

是的,我知道。但我不明白为什么。 【参考方案1】:

jobs.addAll((List) results.values);

addAll() 将指定集合中的所有元素按照指定集合的​​迭代器返回的顺序附加到此列表的末尾。

 @Override
        protected void publishResults(CharSequence constraint, FilterResults results) 
            jobs.clear();
            jobs.addAll((List) results.values); // Issue here
            notifyDataSetChanged();

        
    ;

在 Java 中,可以为对象引用分配一个特殊的 null 值。 当应用程序尝试使用 具有 null 值的对象引用。

您的(List) results.values返回null。首先调试(添加断点)values 是否存在FilterResults results。在投射到列表之前,请确保 results.values 有数据。

代码编辑

package com.example.oddsynew.Home;

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.oddsynew.Modals.Job;
import com.example.oddsynew.R;
import com.squareup.picasso.Picasso;

import java.util.ArrayList;
import java.util.List;

public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder> implements Filterable 

    Context context;

    private ArrayList<Job> alListData;
    private ArrayList<Job> alListFiltered;


    public HomeAdapter(Context c, ArrayList<Job> j) 
         context = c;
         this.alListData = j;
         this.alListFiltered = j;
    

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
        return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.job_row, parent, false));
    

    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) 
        holder.recruiterName.setText(alListFiltered.get(position).getRecruiter_name());
        holder.jobName.setText(alListFiltered.get(position).getJob_name());
        holder.jobLocation.setText(alListFiltered.get(position).getLocation());
        holder.jobCharge.setText(alListFiltered.get(position).getJob_charge());
        Picasso.get().load(alListFiltered.get(position).getProf_pic()).into(holder.profPic);

        holder.itemView.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                try 
                    Intent intent = new Intent(context, JobInfo.class);
                    intent.putExtra("recruiterName", alListFiltered.get(holder.getAdapterPosition()).getRecruiter_name());
                    intent.putExtra("jobName", alListFiltered.get(holder.getAdapterPosition()).getJob_name());
                    intent.putExtra("jobCharge", alListFiltered.get(holder.getAdapterPosition()).getJob_charge());
                    intent.putExtra("jobLocation", alListFiltered.get(holder.getAdapterPosition()).getLocation());
                    intent.putExtra("profPic", alListFiltered.get(holder.getAdapterPosition()).getProf_pic());
                    intent.putExtra("startDate", alListFiltered.get(holder.getAdapterPosition()).getStart_date());
                    intent.putExtra("endDate", alListFiltered.get(holder.getAdapterPosition()).getEnd_date());
                    intent.putExtra("startTime", alListFiltered.get(holder.getAdapterPosition()).getStart_time());
                    intent.putExtra("endTime", alListFiltered.get(holder.getAdapterPosition()).getEnd_time());
                    intent.putExtra("jobDesc", alListFiltered.get(holder.getAdapterPosition()).getJob_desc());
                    intent.putExtra("jobTasks", alListFiltered.get(holder.getAdapterPosition()).getJob_tasks());
                    intent.putExtra("addPref", alListFiltered.get(holder.getAdapterPosition()).getAdd_pref());
                    intent.putExtra("jobID", alListFiltered.get(holder.getAdapterPosition()).getJobID());
                    context.startActivity(intent);
                 catch (Exception e) 
                    e.printStackTrace();
                
            
        );
    

    @Override
    public int getItemCount() 
        return alListFiltered.size();
    

    @Override
    public Filter getFilter() 
        return searchFilter;
    

    @Override
    public Filter getFilter() 
        return new Filter() 
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) 
                String charString = charSequence.toString();
                if (charString.isEmpty()) 
                    alListFiltered = alListData;
                 else 
                    List<Job> filteredList = new ArrayList<>();
                    for (Job row : alListData) 


                        if (row.getJob_name().toLowerCase().contains(charString.toLowerCase())) 
                            filteredList.add(row);
                        
                    

                    alListFiltered = filteredList;
                

                FilterResults filterResults = new FilterResults();
                filterResults.values = alListFiltered;
                return filterResults;
            

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) 
                alListFiltered = (ArrayList<Job>) filterResults.values;
                notifyDataSetChanged();
            
        ;
    


    class MyViewHolder extends RecyclerView.ViewHolder 
        TextView recruiterName, jobName, jobLocation, jobCharge;
        ImageView profPic;

        public MyViewHolder(@NonNull View itemView) 
            super(itemView);
            recruiterName = itemView.findViewById(R.id.recruiterName);
            jobName = itemView.findViewById(R.id.jobName);
            jobLocation = itemView.findViewById(R.id.jobLocation);
            jobCharge = itemView.findViewById(R.id.jobCharge);
            profPic = itemView.findViewById(R.id.prof_pic);
        
    


【讨论】:

我是安卓新手。你能告诉我如何解决这个问题吗?你的意思是说我的results 返回null? @Devika.S strv.com/blog/debugging-in-android-studio-as 谢谢!我调试了。显然,我的结果是空的。我试图找出原因。如果你发现了什么,请告诉我。 @Devika.S @Override protected void publishResults(CharSequence charSequence, FilterResults filterResults) jobs = (ArrayList&lt;Job&gt;) filterResults.values; notifyDataSetChanged(); @Devika.S 删除 public HomeAdapter(ArrayList&lt;Job&gt; jobs) this.jobs = jobs; jobsListFull = new ArrayList&lt;&gt;(jobs);

以上是关于为啥我的数组列表即使在初始化后也会抛出空指针异常?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 Linq 方法会抛出空引用异常

为何将未被初始化的Integer变量赋值给int变量时会抛出空指针异常?

为何将未被初始化的Integer变量赋值给int变量时会抛出空指针异常?

为啥即使使用了调用,组合框也会抛出异常

为啥即使我 .catch() Promise.all() 也会抛出异常?

JSONObject 创建抛出空指针异常