Declaring an Iterator - java

I am having trouble with the syntax on an iterator I created. I would use a for-each loop, except I need to edit the elements that I would be pulling out of that loop. I created a class called Players which creates a List of 4 Hands(Hand is another class that represents an individual player) in a card game. I am trying to create an iterator for this class, which is giving me trouble. My implementation is as follows:
public class Players
{ ....
public class PlayerIterator implements Iterator<Hand>
{
private final Iterator<Hand> iterator;
private PlayerIterator()
{
this.iterator = players.iterator();
}
....
}
}
As far as I know, my implementation seems correct, based on the fact that I havent received any errors in eclipse. I am, however, having trouble declaring an iterator in the actual program. How would I declare an iterator like that?
Right now this is giving me an error:
Iterator<Hand> it = Players.PlayerIterator();
Hand: The class of variables I am iterating through: a list of 4 Hands
Players: The class that constructs the list of Hands and contains the iterator implementation
PlayerIterator: The class within the Players class that implements the iterator
Does this make sense? I have a very loose grasp on iterators, so if I have not provided enough information I could easily create more.

It is a bit difficult to tell from the code you have posted, but I think you might just be missing a new keyword. I assume you have something like the following outside of the Players class:
Players players = new Players();
where an instance of the Players class has some collection of Hands as one of its fields. In this case what you want to do is this:
Iterator<Hand> iterator = players.new PlayerIterator();
However, it also looks like you might have intended PlayerIterator to be a static class, which would be needed if the Players class has a static collection of Hands:
private static List<Hand> players = new ArrayList<Hand>();
Then you want to do this:
Iterator<Hand> iterator = new Players.PlayerIterator();
If you could post more of your code, it would be easier to guide you to the right solution. Another option might be to make Players implement Iterable<Hand>, which means you can directly loop over a Players instance in a for-each loop.

I don't see the point of creating a Hand iterator when your already have a list of Hands in your class. It's hard to understand what your code is trying to do, but if I understand your scenario correctly, the following should suffice:
public class Players implements Iterable<Hand> {
List<Hand> hands = ...
//...
#Override
public Iterator<Hand> iterator() {
return hands.iterator();
}
//...
}

Related

Why I can't add CustomType ArrayList to ArrayList of Object ArrayLists?

I have Singleton class like this:
public class Singleton
private static Singleton instance;
private ArrayList<Release> releases;
private ArrayList<Place> places;
ArrayList<ArrayList<Object>> list = new ArrayList<ArrayList<Object>>(2);
private Singleton() {
releases = new ArrayList<Release>();
places = new ArrayList<Place>();
list.add(release); //error, required AL<Object>, provided AL<Release>
list.add(places); //same
}
public static Singleton getInstance(){
/* Singleton code */
}
I thought that it is possible because, every Class extends Object class. My intention is to read from files where ALs are saved as object a then these ALs have in collection of one AL, where al.get(PLACES_INDEX) would return places and so on. It is a good approach or am I missing something?
Later on I would like to have some unified method, which would be something like:
public ArrayList<T> getArrayList() {
/*return places or releases based on <T>*/
}
I don't know if it's even possible since this class is Singleton.
I will explain why you're getting the error, but from what you describe this looks like a bad design for your class: don't store "generic" lists in a list, to access them based on a certain index. And don't create a method like public ArrayList<T> getArrayList() { that returns one of the lists depending on the type T. This is overengineering, and makes your code much harder to maintain, and easy to break.
Just keep the distinct lists separately, and provide getters for each one of them. If you are reading from a file and want to deserialize the content into a data structure, simply create a class structure that models the content. Your code will be much simpler and easier to read.
Even though Release is a subclass of Object, ArrayList<Release> is not a subclass of ArrayList<Object>, therefore you cannot add an ArrayList<Release> to an ArrayList<ArrayList<Object>> (we say that generics are not covariant). If Java allowed you to do that, then you can end up with a scenario that breaks generic usage of the code:
ArrayList<ArrayList<Object>> list = new ArrayList<>();
ArrayList<Release> releases = new ArrayList<>();
list.add(releases); // imagine this is allowed
ArrayList<Object> releasesFromList = list.get(0);
releasesFromList.add(place); // oops, added a place to list of release

Keeping track of all instances of a subclass in the superclass

I have the following, stripped-down Java code:
// Class, in it's own file
import java.util.*;
public class Superclass {
protected List<Subclass> instances = new ArrayList<>();
public class Subclass extends Superclass {
private int someField;
public Subclass(int someValue) {
this.someField = someValue;
updateSuperclass();
}
private void updateSuperclass() {
super.instances.add(this);
}
}
}
// Implementation, somewhere else, everything has been imported properly
Superclass big = new Superclass();
Subclass little1 = big.new Subclass(1);
Subclass little2 = big.new Subclass(2);
Subclass little3 = big.new Subclass(3);
I want to implement a method in Superclass to do something with all the Subclasses. When a Subclass is created, it should add itself to a list in Superclass, but whenever I try to loop through that list in Superclass, it says the size is 1. The first element in the list (instances.get(0)) just spits out a String with all the proper information, but not in object form, and not separately. It's like every time I go to add to the list, it gets appended to the first (or zeroeth) element in String form.
How can I solve this so I can maintain an ArrayList of Subclasses to later loop over and run methods from? I'm definitely a beginner at Java, which doesn't help my case.
If all you need is a count then I suggest a static value that is updated in the constructor of the parent class.
private static int instanceCount = 0;
public Constructor() {
instanceCount++;
}
If you absolutely need every instance in a list so you can do something with them then I recommend you strongly re-consider your design.
You can always create a utility class that will let you maintain the list of objects to run processes on. It's more "Object Oriented" that way. You can also create one class that has all of the operations and then a simpler bean class that has only the data values.
But, if you insist, you can still use the same technique.
private static List<SuperClass> list = new LinkedList<SuperClass>;
public Constructor() {
list.add(this)
}
Each instance gets its own copy of your superclass's variables.
What you want to do is make the variable "static" by putting the static keyword before it. You probably don't even need the superclass accomplish what you're trying to do.

Calling a specific member of an object array from another class-method

I am now working on the AI section of my project. I am calling a method from my AI class which is intended to calculate where the Gladiator objects I have drawn need to actually end up. I passed to that method a List containing all my objects I want to place. A previous method from the AI class has determined where they want to be from each other, distance-wise and I have stored it as gladiator[0..1..2..etc].movementGoal.
Although the project is not real time, ie I will want to just "step" through it in the end, I do want simultaneous movement to occur. This means that my standard method of iterating through the list will not work as I need information about the other Gladiator's movement decisions in order to figure out any one Gladiator's actual movement as these decisions interact.
How can I access another specific gladiator's variables when I am outside the class and only have them in List form?
Edit:
I guess I could iterate through and test for a variable gladiatorNumber to be correct, then when it is pull that info? That would be pretty round-about but its all I can think of.
Edit2:
As requested, some code. My method in Ai class looks like this:
public void moveAI(List<Gladiator> gladiators) {
My gladiator is defined as such:
public class Gladiator {
Gladiator class is created as an array then added into a list in a separate main class. I don't really want to include more code than this, as there is a ton of it. Basically it boils down to how can I call gladiator[0] from AI class even though I created said object in the main class and only have them in list form in the AI class. Assume all variables in Gladiator are public. The error I am getting is cannot find symbol referring to gladiator[0...1...2...etc].
I think your problem boils down to wanting to pass the arrays of gladiators to another class. That should be fairly easy. If you in your main-class have these two defintions (note you only need one, I recommend the list as it is more versatile, arrays have fixed-length).
You want something like this:
public class Main {
// ....stuff
// This is the main class that keeps the list of gladiators
private List<Gladiator> gladiatorsList;
private Gladiator[] gladiatorsArray;
private MovementAI movementAI;
public Main() {
// You initialize gladiatorsList and gladiatorsArray as before
// gladiatorsList = ...
// gladiatorsArrray = ...
// Now you want to pass this list/array to another class (the AI), you
// can do this in the constructor of that class like so:
movementAI = new MovementAI(gladiatorsList);
}
// ...stuff as before
}
The AI
public class MovementAI {
private List<Gladiator> gladiators;
// Giving the class the list-reference, this list will be the same as the
// list in main, when main-list changes so does this one, they point to the
// same list-object, so the reference is only needed once.
public MovementAI(List<Gladiator> gladiatorsList) {
this.gladiators = gladiatorsList;
}
// The class already has a reference to the list from its constructor so it
// doesn't need the list again as a parameter
public void moveAI() {
}
// If you don't want to keep a reference to the list in this class but only
// use it in a method (I would not recommend this)
public MovementAI() {
}
// You need to pass it gladiatorsList everytime you call this method.
public void moveAI(List<Gladiator> gladiators) {
}
}
I see in your last comment that you have decided to let the AI decide to repaint if it meets a criteria, that is not recommended, you should keep responsibilities separate in your classes, less error-prone and better development. It is recommended to let the AI change the list of gladiators (move them, kill them etc) and the rendererclass simply paint every gladiator.
It also seems you want to have every gladiator be able to hold another gladiator as a target, it is better for them to hold the target as an Object, this way you don't have to search the entire list to find out which gladiator the gladiatornumber refers to and you don't have to think about ordering in the list. Something like this:
public class Gladiator {
// ..other stuff
private Gladiator target;
public Gladiator getTarget() {
return target;
}
public void setTarget(Gladiator target) {
this.target = target;
}
}

Having trouble with adding an ArrayList to an ArrayList of ArrayLists

public class Tabel {
private static int dimension;
private ArrayList<ArrayList<Character>> tabel;
public Tabel(int dimension) {
Tabel.dimension = dimension;
for (int i=0;i<Tabel.dimension*Tabel.dimension;i++) {
tabel.add(new ArrayList<Character>());
}
}
}
When I try to debug (eclipse ide) I get a lot of weird "errors" or at the very least I encounter something I consider unexpected.
The private static int does not appear in the "variables" section of debug.
I get a NullPointerException on tabel.add(...) but when I watch the debug, it enters the for once, does not add anything in the table because when I hit "next" instead of jumping to the closing braces it jumps out of the function.
If I comment the .add it works so that's the problem (I think). Is my syntax wrong ? or should I post more code ?
tabel is not initialized, so it is null.
Change
private ArrayList<ArrayList<Character>> tabel;
to
private ArrayList<ArrayList<Character>> tabel = new ArrayList<ArrayList<Character>>();
Or better:
private List<ArrayList<Character>> tabel = new ArrayList<ArrayList<Character>>();
since this does not tie tabel to ArrayList.
You have not initialized the private List. Do the following:
private List<ArrayList<Character>> tabel = new ArrayList<ArrayList<Character>>();
I'd have trouble understanding that level of nesting too.
It's better to refer to List rather than ArrayList. Unless you need a method in the concrete class, it makes your program more flexible to refer to the interface and the methods in the interface.
Create a class (1) that has a field defined as a List of Character. Set the field to a new ArrayList in the constructor.
Create another class (2) that has a field defined as a List of class (1). Set the field to a new ArrayList in the constructor.
Create another class (3) that has a field defined as a List of class (2). Set the field to a new ArrayList in the constructor.
Since you understand what you're doing, you can give these 3 classes more meaningful names.

Java: using iterators in other classes

I'm running into problems trying to put a public iterator in a class to read a Map in the class and implementing this iterator in other classes. Or in other terms,
I have class A. Class A contains a private HashMap that I want to access through a public iterator that iterates this map.
I also have class B. I'm trying to run this iterator in class B to read the contents of class A.
This may seem a bit roundabout (or rather, a lot roundabout), but my assignment specified that the data system in class A be hidden to other classes and suggested using a public iterator to access the data. There is an example of what the method in class B might look like, which I've followed to the best of my ability.
Can't get it to work, though.
Here's a mockup of the code I have. I tried compiling it, and it works exactly as my real code.
// this is class A
public class Giant {
private Map<Item, Integer> myMap = new HashMap<Item, Integer>();
// add a bunch of items to the map, check if they worked fine
public Iterator<Map.Entry<Item, Integer>> giantIterator = myMap.entrySet().iterator();
}
// and this is in class B
public void receive(Giant mouse){
System.out.println("I've started!");
Iterator<Map.Entry<Item, Integer>> foo = mouse.giantIterator;
while (foo.hasNext()) {
Map.Entry<Item, Integer> entry = foo.next();
System.out.println("I'm working!");
}
}
I also have a testclass which creates objects of either class and then runs the receive method.
I receive the message "I've started!" but not "I'm working!"
At the same time, if I have the two iterators in either class print a toString, the toStrings are identical.
I can't simply move the actions I'm supposed to do in class B to class A either, because the iterator is in several different methods and is used for slightly different things in each.
I'm a bit stumped. Am I missing something from the syntax? Am I importing something wrong? Have I just completely messed up how this is supposed to work? Is this just flat out impossible?
Try exposing the iterator through a function like this:
public class Giant {
private Map<Item, Integer> myMap = new HashMap<Item, Integer>();
public Iterator<Map.Entry<Item, Integer>> getGiantIterator() {
return myMap.entrySet().iterator();
}
}
And in class B change:
Iterator<Map.Entry<Item, Integer>> foo = mouse.giantIterator;
to
Iterator<Map.Entry<Item, Integer>> foo = mouse.getGiantIterator();
That way the iterator will not be created until it is needed.
The way you have coded it, the iterator is created while the map is still empty. I suspect this may be the root of your problem.
Your iterator is constructed when A is constructed, and at that time the Map is empty.
Make a method getIterator() that returns an up to date version.
If you have one iterator, and you want various classes to access it, then set that variable to "static".

Categories

Resources