I have a superclass called "Items" and a sub class called "PickUpHealth1". I create an array of Items similar to this code:
ArrayList<Items> itemsArray = new ArrayList<Items>();
Items h1 = new PickUpHealth1(x,y);
itemsArray.add(h1);
The subclass has it's own methods. I go through the array itemsArray and when a certain event occurs I want to initiate methods in the subclass PickUpHealth1. I know that the superclass doesn't know about the methods in the subclass but I don't want to create a separate array for each subclass if possible. Is there anyway I can reference the methods in the subclass through itemsArray? Since h1 is initialized as an object of PickUpHealth1 I would think there should be a way to do this, but I can't figure it out. Is there a way? Or am I going about it all wrong? Thanks.
So PickUpHealth1 extends Item and you have a List<Item> items
As you've noted Items can only do Item things, so you can't go trying to use PickUpHealth1 methods when you are accessing it as an Item through the items list.
If Items don't have anything in common then don't extend from it.
If they are all "useable" then give them a common method.
For example:
abstract class Item {
public abstract void useItem();
}
class PickUpHealth extends Item {
private int healAmount;
public PickUpHealth(int healAmount) {
this.healAmount = healAmount;
}
#Override
public void useItem() {
player.addHealth(healAmount);
}
}
public static void main(String[] args) {
List<Item> items = Arrays.asList(new PickUpHealth(10));
Item item = items.get(0);
item.useItem();
}
Related
Basically, when I passed arguments in Java, I knew it was passing only value.
However, the following code shows that the add method executed on SubClass's SubMethod affects ArrayList of MainClass.
MainClass.java
public class MainClass{
public satatic void main(String[] args){
List list = new ArrayList<>();
SubClass subClass = new SubClass(list);
subClass.subMethod();
System.out.println(list) // Why added value???
}
}
SubClass.java
public class SubClass{
private List list;
public SubClass(List list){
this.list = list;
}
public void subMethod(){
list.add(1);
list.add(2);
}
}
When I did the same thing with a HashMap's put, there was no effect on the HashMap of the MainClass.
I would like to know why only ArrayList is causing these results and what is happening inside Java.
Update
The code for the hashmap version is as follows:
MainClass.java
public class MainClass{
public satatic void main(String[] args){
Map map = new HashMap<>();
SubClass subClass = new SubClass(map );
subClass.subMethod();
System.out.println(map) // Not putting value
}
}
SubClass.java
public class SubClass{
private Map map;
public SubClass(Map map){
this.map= map;
}
public void subMethod(){
map = someGenerationHashMap(arg1, arg2);
}
}
It's not about ArrayList. Any object you pass as an argument can be modified. What is passed by value is the address of the object, not the object itself.
In the Map version, you are not making any operation that could modify it. In the list version instead, you are making an add.
Make sure not to confuse objects with primitives. For example, make sure not to confuse int with Integer.
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 have these classes:
public class class0{
private ArrayList<class1> array;
...
public void remove(Class1 class1){
array.remove(class1);
}
}
public class class1{
private Class2 array;
}
public class class2{
private ArrayList<class1>;
}
Is it possible that, when I remove an object of class1 using the given method, automatically deletes that instance from every arraylist that derivates from class1?
(Without going through every list, checking is equals and "remove")
Lets say you are doing this:
ArrayList<Class1> array = ArrayList<Class1>();
public void add(Class1 class1){
array.add(class1);
}
public void remove(Class1 class1){
array.remove(class1);
}
public static void main(String argv[]){
Class1 class1 = new Class1();
Class1 class2 = new Class1();
new class0.add(class1);
new class0.add(class2);
new class0.remove(class1);
}
by doing this only array list of class1 object is removed.. and nothing else. class2 object of class1 will still be there and no other lists are deleted
Unless these two lists are the same instance, removal of an element from one list does not impact removal from another list. You will have to go through each one and remove the element from each.
ArrayList<'class1> array; // This won't allow anything else but objects of class1
So deleting all objects of class1 is equivalent to clearing the entire array.
If you define: ArrayList array; // without <class1>
then you can iterate through it and see if entry is of a type by using:
instanceof
and then delete it.
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.
I have a class that implements getter and setter methods and related code as follows.
ArrayList<String> viewArray = new ArrayList<String>();
public ArrayList<String> getView() {
return viewArray;
}
from my activity, I am trying to get acces to stored array like:
ArrayList<String> al = new ArrayList<String>();
al = parsedExampleDataSet.getView();
But "al" receives no data. However, when getView() is executed, viewArray is filled properly. What am I missing? Thank you.
Others have make some good comments but I thought I'd take you through the code as I see it.
public class SomeClass {
// this is local to this class only
ArrayList<String> viewArray = new ArrayList<String>();
public void process() {
// i'm guessing there is some sort of processing method that is called
}
public ArrayList<String> getView() {
return viewArray;
}
}
Here's your activity class annotated with some details about the value of a1:
public class YourActivity {
ArrayList<String> al = new ArrayList<String>();
public void someMethod() {
// here a1 will be the same blank List you initialized it with
// unless someMethod() has been called before or a1 modified elsewhere
al = parsedExampleDataSet.getView();
// after the call to getView, a1 is now a reference to SomeClass.viewArray
// the ArrayList that a1 was initialized with is then garbage collected
}
}
Please edit your question to explain more what you are having problems with.