This should be something fairly simple but I can't figure out my error. First up I am trying to write a program which will take user input and add the input as an object to a list called aList. I have two classes one called Group and one called ListObject.
Here is the Group class code
public class Group
{
List<ListObject> aList = new ArrayList();
public Group()
{
}
public void addObject(Object aName)
{
aList.add(aName);
}
}
Here is my ListObject class
public class ListObject
{
private String name;
public int value;
/**
* Constructor
*/
public ListObject(String aName)
{
super();
this.name = firstName;
this.value = 10;
}
}
I need the method in the Group class to take user input, create an object of that name and then add it to the list aList and have all objects in that list be assigned as value of -1 to begin with. For some reason I am being returned a NullPopinterException. Hopefully you can point out what I've missed. Please note I did have this working when I was just adding strings instead of instances of the ListObject Objects.
Change your code as follows :
public class Group {
List<ListObject> aList = new ArrayList();
public Group() {
super();
}
public void addObject(ListObject aName) {
aList.add(aName);
}
}
There were two problems with your code :
The aList local variable that you re-defined within the constructor was hiding the the aList instance variable. You ended up intializing the local variable aList in the constructor instead of initializing the aList instance variable. Therefore, the instance variable was always be null and you got a NullPointerException when you called the add method in addToList on a null reference.
Your list is declared as List<ListObject>. This means that the list can only hold objects of type ListObject. This is known as type-safety. The argument of the addObject method should be changed to ListObject. Also note that you need to create a ListObject and pass it to the addObject method.
Related
I am trying to up create and update an ArrayList by passing an argument, so that I will end up with a list of say 10 names; however, the current function doesn't seem to be working - any ideas pls?
public String addClient(String name) {
ArrayList<String> myList = new ArrayList<String>();
myList.add(name);
return myList;
}
You are creating a new ArrayList every time you call it. This means that every time you call this method you create a brand new Collection and only store the one client in it. You need to keep a reference of a single collection around and keep adding to that. You can do that by passing in the array you want to add it to:
public List<String> addClient(String name, List<String> array) {
array.add(name);
return array;
}
This doesn't seem like a useful function, so I'm guessing this is within a class. So this might be the approach you want:
/**
* Class is not Thread Safe
*/
public class ClientList {
private final ArrayList<string> clients;
public ClientList() {
this.clients = new ArrayList<>();
}
public void addClient(String client) {
this.clients.add(client);
}
public List<String> getClients() {
// Note: Never give a reference to the internal objects of the class
// as that means someone outside this class can own a reference to it
// and can update the object without you knowing (by not going
// through this class)
Collections.unmodifiableList(this.clients);
}
}
This is what you need to do:
ArrayList<String> myList = new ArrayList<String>();
public void addClient(String name) {
myList.add(name);
}
If you create a list inside the method, it will only have one value, and will go away once method execution finishes (unless it's returned). Have a look at different scopes here. You should create a list at a class level and add the elements into it.
Also, method does not need to return anything, so it's better to change the type to void.
The problem with your approach is that everytime you call the method addClient a new ArrayList will be created.
I think this will work for you :
static ArrayList<String> myList;
public static void main(String[] args) {
myList = new ArrayList<>();
}
public void addClient(String name){
myList.add(name);
}
I am working on a project, and I was taught to instantiate variables in constructors. I'm having some trouble doing this with an ArrayList thought. Can you suggest some best practices, do I need to define the ArrayList with the instance variables or can I do it in the constructor. Thanks for your suggestions! I have an example of what I'm talking about below:
//imports
import java.util.*;
import java.lang.*;
public class ArrayListConstructorDemo
{
//instance variables/attributes
String string;
List<String> list;// for example does this line need to say List<String> list = new ArrayList<String>();
//constructors
public ArrayListConstructorDemo()
{
String string = "null";
List<String> list = new ArrayList<String>();//is there anyway I can do this here instead of 6 lines up?
}//end default constructor
public ArrayListConstructorDemo(String string,List<String> list)
{
this.string = string;
this.list = list;
}//end generic constructor
//observers/getters/accessors
public String getString(){return string;}//end method getString()
public List<String> getList(){return list;}//end method getList()
//transformers/setters/mutators
public void setTable(String string){this.string = string;}
public void setValues(String list)
{
// for(String s : test)
// {
list.add(this.list);
// }
}
public String toString()
{
return "this is a generic toString method for the class ArrayListConstructorDemo";
}//end toString
public static void main(String[] args)
{
ArrayListConstructorDemo alcd = new ArrayListConstructorDemo();
System.out.println(alcd.list.size());
//test Lists in general
List<String> bleh = new ArrayList<String>();
bleh.add("b1");
System.out.println(bleh.get(0));
}//end method main()
}//end class ArrayListConstructorDemo
Change
List<String> list = new ArrayList<String>();
to
list = new ArrayList<String>();
If you want to just declare it in the constructor you can have the code:
ArrayList<String> name = new ArrayList<String>();
Otherwise you can declare it as a field, and then initialize it in the constructor.
private ArrayList<String> name;
And then in the constructor:
name = new ArrayList<String>();
Making it a field would be useful, as you would then be able to create accessor/mutator methods in order to retrieve and use the List from different classes, without having to declare it public (which is rarely a good thing).
If you want to declare it in the constructor, then you (most likely) want to declare the outer field, so you want:
list = new ArrayList<String>();
Currently you are shadowing the List<String> list class variable, meaning that you are creating a new instance of list, rather than that you are initializing the list instance variable.
I personally prefer initializing it at declaration time though, so what you previously had. I prefer this to make the code more concise and you most likely won't end up forgetting to initialize it if you teach yourself that habbit.
Generally the practice is to declare before the constructor, and initialize in the constructor.
Here's an example:
class myClass
ArrayList<String> strings
public myClass()
{
strings=new ArrayList<String>();
}
How can you do this ??
public void setValues(String list) {
// for(String s : test)
// {
list.add(this.list);
// }
}
There is no method like add() to manipulate Strings, Instead you would have done this :
public void setValues(List<String> list) {
// for(String s : test)
// {
list.add(this.list);
// }
}
And regarding declaring ArrayList in the constructors you can do like this :
String string;
List<String> list;// for example does this line need to say List<String>
// list = new ArrayList<String>();
// constructors
public ArrayListConstructorDemo() {
string = "null";
list = new ArrayList<String>();// is there anyway I can do this here
// instead of 6 lines up?
}// end default constructor
java offers you also an Initializing Fields
http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html see Initializing Instance Members
So let say I have such prototyping:
private static Hashtable<String, Furniture> map =
new Hashtable<String, Furniture>();
public My_product() {
loadCache();
}
public My_Product createProduct(String type, String name) {
Furniture cachedproduct = map.get(type);
return (Furniture) cachedproduct.clone();
}
private static void loadCache() {
Sub_product1 pr1 = new Sub_product1(null);
map.put("pr1", pr1);
Sub_product2 pr2 = new Sub_product2(null);
map.put("pr2", pr2);
}
So when I make an instance of an object, I don't know what value will be entered after cloning it (creating object using cloning). So I chosen null value for object instance. But when I clone it then I know what value needs to be assigned for that object. So how could I specify while cloning to put some value instead of null one from object instance?
As you can see in method createProduct method, there is argument called name. I would like that name to be used in cloned object, but how could I do that?
Can you use setter methods?
public My_Product createProduct(String type, String name) {
Furniture cachedproduct = map.get(type);
Furniture clonedProduct = (Furniture) cachedproduct.clone();
clonedProduct.setType(type);
clonedProduct.setName(name);
return clonedProduct;
}
However, I'm still not clear on the whole idea of this cloning of cached objects from the map. Is your product instantiation very expensive? What's the trick?
You cannot pass arguments through the Java built-in clone mechanism. You could provide a setter on the Furniture class to change the name after it has been cloned.
Note that cloning in Java is generally considered broken. It is a brittle way to create objects. Generally you are better of using the factory pattern, e.g. something like:
interface FurnitureBuilder {
Furniture build(String name);
}
class SubProduct1Builder implements FurnitureBuilder {
public Furniture build(String name) { return new SubProduct1(name); }
}
class MyFurnitureFactory {
private final Map<String, FurnitureBuilder> builderByType = ...
// initialization omitted
public Furniture create(String type, String name) {
return builderByType.get(type).build(name); // null check omitted!
}
}
When creating a method inside a class if you use the parameter:
public String Method(ClassName NewObject){}
or in my example below:
public String EqualsTo(Deck aCard){}
will it create a new object of that class within that method? If not anyone mind explaing what I is happening with that parameter?
NOTE: Disregard any minor syntax errors as I just constructed this to get my question across better so this is not a complete class.
import java.util.Scanner;
import java.util.Random;
public class Deck {
private int suit;
private int rank;
private Random generator = new Random();
Scanner in = new Scanner(System.in);
//Default constructor
public Deck() {
suit = suit.random(4);
rank = rank.random(13);
}
public String EqualsTo(Deck aCard){}
}
Objects are created when you use the new keyword. On the other hand, when you declare a method as
public String EqualsTo(Deck aCard){}
it says that the EqualsTo() method takes a Deck reference as a parameter. In order to use the method, you need to create a Deck object and keep a reference to it. Then you send the reference to the method.
That parameter act as a place holder for that type of object. It doesn't actually create it, the method signature says:
I'm an EqualsTo() method and I take/require a Deck type of instance/object as a parameter.
It return a String as a result.
By the way, I recommend using a boolean as the return type instead of a 'String' for an EqualsTo method.
Fundamental thing: Java is pass by value.
A new object is not created.
Object reference value created by the calling entity is copied to the method argument aCard.
Any modifications done on this object will remain visible to the calling entity. This is because the reference value is pointing to the same address location of the object.
Here's an example.
public class Test2 {
public int bla;
public static void main(String[] args) {
Test2 test = new Test2();
test.bla = 878;
test.doSome(test); // Calling Location
System.out.println(test.bla);
}
public void doSome(Test2 test) {
test.bla = 95;
}
}
NO
public String EqualsTo(Deck aCard){}
Does not create a new object when it is called.
Here is where the objects are created. Use case
Deck deck1 = new Deck(); // NEW OBJECT CREATED
Deck deck2 = new Deck(); // NEW OBJECT CREATED
String result = deck1.EqualsTo(deck2); // NO NEW OBJECT CREATED,
// JUST PASSED REFERENCE OF EXISTING OBJECT
// (except the result of course, which is probably a new object)
I've just been experimenting and found that when I run the rolling code, it does not compile and I can't figure out why.
My IDE says 'Cannot make a static reference to the non-static field list', but I don't really understand what or why this is. Also what else does it apply to, i.e.: is it just private variables and or methods too and why?:
public class MyList {
private List list;
public static void main (String[] args) {
list = new LinkedList();
list.add("One");
list.add("Two");
System.out.println(list);
}
}
However, when I change it to the following, it DOES work:
public class MyList {
private List list;
public static void main (String[] args) {
new MyList().exct();
}
public void exct() {
list = new LinkedList();
list.add("One");
list.add("Two");
System.out.println(list);
}
}
static fields are fields that are shared across all instances of the class.
non-static/member fields are specific to an instance of the class.
Example:
public class Car {
static final int tireMax = 4;
int tires;
}
Here it makes sense that any given car can have any number of tires, but the maximum number is the same across all cars.
If we made the tireMax variable changeable, modifying the value would mean that all cars can now have more (or less) tires.
The reason your second example works is that you're retrieving the list of a new MyList instance. In the first case, you are in the static context and not in the context of a specific instance, so the variable list is not accessible.
In the first example you are calling non-static field from static content, which is not possible.
In the second one you are calling ext function on MyList object, which has access to that field.