I was making a food ordering application where I got stuck. I am calling the constructor of my class. Then, after assignment, this.listData my ArrayList is being reported redundant.
public class CartAdapter extends RecyclerView.Adapter<CartViewHolder> {
private List<Order> listData = new ArrayList<>();
private Context context;
public CartAdapter(List<Order> listData, Context context) {
this.listData = listData;
this.context = context;
}
}
Probably your IDE gives you the message that the following initialisation is redundant, not the field itself.
private List<Order> listData = new ArrayList<>();
The idea is that you have only one constructor, and this constructor expects all the time a List<Order>. This means that each time you make an instance of the class, you will be able to use the only constructor you provided, in which the field listData will have the value of the first parameter of the only constructor, so there is no need to initialize the field like that. This is why you get the "redundant initialisation" warning.
If you want to have a way of initialising the listData as an empty ArrayList, then you can provide an constructor where you don't handle the listData field. Otherwise, declaring private List<Order> listData; will do "the trick".
Related
I'm trying to create a reusable Class on Android that fetches Users data from a Firebase Database, creates a list of Users Models, and returns that list to any other classes that might need the list. But I'm not being able to do it. I won't bother you with all the code, but what I got is basically this:
Class Reusable {
//declare FireBase Auth, DatabaseReference, etc.
private Context mContext;
private List<Users> mUserList;
public Reusable (Context context){
mContext = context;
mUserList= new ArrayList<>();
}
}
public void getUsersIdFromDb(){
List<Strings> idList = = new ArrayList<>();
//gets Users Id from Database and save it to idList:
idList.addAll(ids); //ids are ids fetched from Database
Log.d("StepOne",Integer.toString(idList.size(); //returns correct number of ids
createListOfModels(idList);
}
private void createListOfModels(final List<Strings> list){
//compares fetched ids with ids inside logged user node
//if it passes:
for(String id: list){
String name = datasnapshot.child(id).child("name).getValue();
String pic= datasnapshot.child(id).child("pic).getValue();
UserModel user = new UserModel(name, pic);
mUserList.add(user);
}
processListOfUsers(mUserList);
}
private void processListOfUsers(List<Users> list){
for (User u: list){
mUserList.add(u);
Set<Users> hs = new LinkedHashSet<>();
hs.addAll(mUserList);
mUserList.clear();
mUserList.addAll(hs);
Log.d("StepThree",Integer.toString(mUserList.size(); //returns correct number of Users
}
}
public List<Users> getList(){
return mUserList;
}
Then, when calling the Reusable class:
public SomeClass extends AppCompatActivity {
//onCreate, etc...
Reusable reusable = new Reusable(SomeClass.this);
reusable.getUsersIdFromDb();
int i = reusable.getList().size();
Log.d("FromSomeClass", Integer.toString(i);
//returns 0 when it should return the size of the List from Reusable;
//How do I get the List From Reusable Class??
}
As you can see from the size of the list at the Log, it is returning an empty list. How should I set Reusable, so that it returns the list when other classes call?
I'm still finding my way through Java and Android, so I'd appreciate your help.
[EDIT] Maybe it has something to do with the fact that Firebase calls are Asynchronous? Because, you see, as long as I'm passing the results to the parameters, the Logs return a full List. But calling a method outside this chain, perhaps triggers its execution outside the Firebase thread, where the list is still empty.
I didn't quite get what the problem is you're trying to solve. If it is the fact that it returns zero then that's because you never fill the list with anything in this code. The list exists, it's just empty.
The Constructor creates an empty list (size 0)
public Reusable (Context context){
mContext = context;
mUserList= new ArrayList<>();
}
Then you actually DO get the list.
First you create a new reusable which creates an empty list inside it
Reusable reusable = new Reusable(SomeClass.this);
Then you get the size of that list which is zero
int i = reusable.getList().size();
There isn't an error here, you just need to fill the list in the constructor or somewhere.
I am trying to add an object of class Track to my ArrayList of Track, playlist.
import java.util.ArrayList;
public class PlayList {
private String playList;
private ArrayList <Track> myTracks;
//constructors
public PlayList(String name) {
this.playList = name;
}
public PlayList(String name, ArrayList<Track> tracks) {
this.playList = name;
this.myTracks = tracks;
}
public addTrack(Track track){
myTracks.add(0,track)
}
}
But both my constructor and addTrack method fails, showing java.lang.NullPointerException
Where am I going wrong?
You never get an exception in your constructor. There is no chance at all.
And the reason for add method is you are using myTracks.add(0,track) and you never initialize your list
private List<Track> myTracks = new ArrayList<Track>();
You need to initialize the ArrayList and code to the interface.
Use : private List<Track> myTracks = new ArrayList<>(); (for java versions below java -7, use new ArrayList<Track>();)
I think your constructor fails because you try to initialize object from playList like this :-
playList myList = new playList();
This will give you error because there is no defualt constructor and it is not created by default (The default constructor is automatically generated unless you define another constructor)
If you didn't create your playList object like this there is no way you got an exception in the constructor
And the reason for addmethod error is you initialized your list
You have to do this :-
private List<Track> myTracks = new ArrayList<Track>();
You are getting "NullPointerException" in the Arraylist because you have not initialized it first. You can add items in list only after initializing it first.
So write like this instead and try -
private List<Track> myTracks = new ArrayList<Track>();
As far as the constructor is concerned i think there you didnt give the required parameters. When you are calling the constructor of PlayList class you need to pass the correct values as parameters which you defined(2 Constructors in this case). if you don't then it will throw an error because there is no default(no argument) constructor. So try like this -
PlayList myList=new PlayList("//give name","//ArrayList name which contains the tracks")
I'm getting myself in a muddle with an ArrayAdapter I'm trying to put together. I've got a constructor, Person, which is used to put together people to go in a list. I'm then putting together an ArrayList of type Person to make a readable list.
I then put together an ArrayAdapter so that the list can be seen in a ListView, but I'm constantly getting "Cannot resolve constructor" with my code.
I've tried countless possible solutions on this site including trying to use getActivity() or this in place of PeopleActivity.this, but I just cannot get my code to compile. I've also tried referencing my constructor class in the ArrayAdapter, but that just gives me an error that it's not an enclosing class.
Person.class (constructor)
import android.text.Editable;
public class Person {
public Person Person;
private Editable personName;
public Person(Editable a) {
personName = a;
}
public void setName(Editable personName){
this.personName = personName;
}
public Editable getName() {
return personName;
}
}
PeopleActivity - populateListView
ArrayList<Person> peoplelistv = new ArrayList<Person>();
...
private void populateListView() {
ListView list = (ListView) findViewById(R.id.peopleListView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(PeopleActivity.this, android.R.layout.simple_list_item_1, peoplelistv);
list.setAdapter(adapter);
}
Any ideas folks?
Thanks
You are declaring the ArrayAdapter as ArrayAdapter<String>. However, the third parameter that you are passing to the constructor is neither a String[] nor a List<String>. If you are trying to wrap an ArrayList<Person> in an ArrayAdapter, it needs to be an ArrayAdapter<Person>, not ArrayAdapter<String>.
Where it is better to initialize fields? In constructor (var.1) or on declaration (var.2)?
var. 1
public class UtilWebLoading {
private int data;
private Context context;
public UtilWebLoading(Context context) {
this.context = context;
data = 100;
}
...
}
var. 2
public class UtilWebLoading {
private int data = 100;
private Context context;
public UtilWebLoading(Context context) {
this.context = context;
}
...
}
In var. 1 the context has been initiated, while in var. 2 it will be null!
Use the first one.
I personally prefer to initialize fields when I have sufficient context to do so. For example, if I have a List field I usually initialize it upon declaration (unless the class requires the user to pass an implementation of their choosing), but if I have an array that requires a size to be passed, I'm forced to wait for a constructor call.
Hence, in your case, the second snippet does not have enough context to initialize Util at declaration, because no valid Context member exists.
Let's say I have this:
public class Whatever {
private ArrayList<String> myList = new ArrayList<String>();
// more code goes here
}
or let's say I have this:
public class Whatever {
private ArrayList<String> myList = null;
public Whatever() {
myList = new ArrayList<String>();
}
}
What's the difference between these two initialisations of myList? Would it be wrong to preffer the first variant?
The first variant will always instantiate the array list, the second one only when calling the default constructor. Meaning for the second solution you will have to call the default constructor for any additional constructor you add e.g.
public class Whatever {
private final List<String> myList;
public Whatever() {
myList = new ArrayList<String>();
}
public Whatever(String name) {
this();
// Other stuff done
}
public Whatever(List<String> myList) {
this.myList = myList;
}
}
The (second) "lazy" initialization method might be better if you don't always use the list (e.g. if you set the list in another constructor directly like in my example) and want to avoid creating unnecessary objects. (EDIT: I changed the ArrayList to an interface and set it final. It wasn't part of the question but it is - as mentioned in the comments - the best way to use List collections).
The JVM first executes code such as this (outside the constructor):
public class Whatever {
private ArrayList<String> myList = new ArrayList<String>();
// more code goes here
}
And only then code such as this (inside the constructor):
public class Whatever {
private ArrayList<String> myList = null;
public Whatever() {
myList = new ArrayList<String>();
}
}
So unless the order of execution is somehow important to you i guess #Daff's answer is the right one.
In this particular example, there is no difference except that the first form is shorter.
However, if the attribute initialization expression (potentially) throws exceptions, the second form allows you to catch the exceptions, or declare them as thrown in the constructor signature.
And of course, if you have multiple constructors, the second form allows you to initialize the attribute differently in each constructor ... or use constructor chaining to initialize the attribute the same ... or mix the two styles of initialization.