I am creating a UI with object oriented programming.
In the UI I am trying to add a new team. When I add this team, I want the object of the team to be stored into an ArrayList named 'TeamList'.
I am able to store the team just fine as an object from the UI, but I cannot add the team into the TeamList ArrayList, and im not sure what I'm doing wrong.
I am new to programming so I apologise for any bad errors.
This is my TeamList class ('Team' is an object I've already created):
public class TeamList {
private ArrayList<Team> teamList;
public TeamList(){
setTeamList(teamList);
}
public ArrayList<Team> getTeamList() {
return teamList;
}
public void setTeamList(ArrayList<Team> teamList) {
this.teamList = teamList;
}
And this is where Im trying to add 'Team' to 'TeamList':
#FXML private void AddingTeam() {
Team team = new Team(newTeamTextfield.getText());
team.getTeamName();
TeamList teams = new TeamList();
teams.add(team);
}
The error is with:
teams.add(team);
Add add() method in TeamList and your list is null by default and in constructor you are assigning instance which is null to itself
//Do below and remove constructor
private ArrayList<Team> teamList = new ArrayList<>();
//or
public class TeamList {
private ArrayList<Team> teamList;
public TeamList(){
setTeamList(new ArrayList<Team>());
}
public ArrayList<Team> getTeamList() {
return teamList;
}
public void add(Team team){
teamList.add(team);
}
public void setTeamList(ArrayList<Team> teamList) {
this.teamList = teamList;
}
}
The object teams isn't an ArrayList, it's a TeamList object. Therefore, you can't use .add() because it is not of type ArrayList.
Make an ArrayList<Team> instead, and then use .add(team) with your new ArrayList.
Use
ArrayList<TeamList> teams = new ArrayList<TeamList>();
to add the team to teams list
Related
So I'm making a plugin and I want to put two ArrayList (of two different teams) to one Hashmap, so I can get both of the teams in this method:
public static Teams getTeam(Player player) {
if (!hasTeam(player))
return null;
return zombiesTeam.get(player) && survivorsTeam.get(player);
}
Here is the two ArrayList and a Hashmap that I want to have:
public static HashMap<zombiesTeam, survivorsTeam> playerTeams = new HashMap<zombiesTeam, survivorsTeam>();
public static ArrayList<Player> zombiesTeam = new ArrayList<Player>();
public static ArrayList<Player> survivorsTeam = new ArrayList<Player>();
P.S. I know that this code isn't correct
Please ask me for any further additional information
Thanks in advance.
You should do something like this:
public static HashMap<String, ArrayList<Player>> playerTeams = new HashMap<>();
playerTeams.put("zombies", zombiesTeam);
playerTeams.put("survivors", survivorsTeam );
If you want to represent all your "teams" by a hashmap from the team name to the list of team members, I would suggest this:
// In the same class where zombiesTeam and survivorsTeam are declared
public static Map<String, List<Player>> getTeamsByName() {
Map<String, List<Player>> teamsByName = new HashMap<>();
teamsByName.put("zombiesTeam", zombiesTeam);
teamsByName.put("survivors", survivorsTeam);
return teamsByName;
}
However, be sure that you need to use static fields and methods. Your model doesn't suggest this.
For instance, you could rather declare a Team class and a Player class. Since you already have the Player class, here is how I would make the Team class:
public class Team {
private String name;
private Set<Player> teamMembers = new HashSet<>();
public Team(String name) {
this.name = name;
}
public String getName() {
return this.teamName;
}
public Set<Player> getTeamMembers() {
return this.teamMembers;
}
public addPlayer(Player player) {
this.teamMembers.add(player);
}
public removePlayer(Player player) {
this.teamMembers.remove(player);
}
public reset() {
this.teamMembers.clear();
}
}
Be sure to override equals and hashcode for HashSet and HashMap to work correctly. More information about this here:https://www.geeksforgeeks.org/equals-hashcode-methods-java/
import java.util.ArrayList;
public class Team {
private String name;
private ArrayList<Player> team;
public Team(String name) {
this.name = name;
//how come i have to initialize it here in the constructor to see the full list?
this.team = new ArrayList<Player>();
}
public void addPlayer(Player player) {
//why can't i initialize it here in the method, this gives me a list of only recent add?
//this.team = new ArrayList<Player>();
this.team.add(player);
}
public void printPlayers() {
for(Player players : this.team) {
System.out.println(players);
}
}
public String getName() { return this.name; }
}
I'm trying to figure out why this.team = new ArrayList<Player>() have to be in the constructor?
Why can't I have this.team = new ArrayList<Player>() initialized in the method?
I know that when I run it with the code in the constructor it works as intended (it gives me the full list when things are added)
BUT when it's initialized in the method it only list the last given addition to the list. Is it wrong to have it initialized in the method?
Also what's the difference of having it initialized as private ArrayList<Player> team = new ArrayList<Player>(); before the constructor?
Answering just the question:
Also what's the difference of having it initialized as private ArrayList<Player> team = new ArrayList<Player>(); before the constructor?
Nothing, aside from the fact that team would be initialized before name.
Field initializers are syntactic sugar for instance initializers. So this:
private ArrayList<Player> team = new ArrayList<Player>();
is identical to this:
private ArrayList<Player> team;
{
// This is an instance initializer.
team = new ArrayList<Player>();
}
and instance initializers are gathered together and inserted into every constructor which invokes (implicitly or explicily) super, in between the call to super and the rest of the constructor body. So this:
public class Team {
private ArrayList<Player> team = new ArrayList<>();
public Team(String name) {
this.name = name;
}
}
is identical to:
public class Team {
private ArrayList<Player> team;
public Team(String name) {
super();
this.team = new ArrayList<>();
this.name = name;
}
}
Because of the fact that each constructor invocation will result in a new distinct object the line this.team = new ArrayList<Player>(); within the constructor will only be called once per instance so thus you'll only ever have one ArrayList instance per object in this specific case.
On the other hand, the addPlayer method can be called as many times as you want on a given object thus this.team = new ArrayList<Player>(); within the addPlayer method will replace (overwrite) the previous list on each method call.
You can do this in that way (to prevent recreation of ArrayList on every addPlayer method call):
public void addPlayer(Player player) {
if (this.team == null) {
this.team = new ArrayList<Player>();
}
this.team.add(player);
}
but it will be VERY weird code... Better practice is to initialize 'team' list inside constructor or inline in field declaration. Both of them do the same thing. I prefer to initialize fields inside constructor, but this is only my habit. Other programmers may prefer inline version and this is nothing wrong/bad.
Why can't I have this.team = new ArrayList() initialized in the method?
You're creating a new ArrayList each time and assigning it to this.team. So each time you call addPlayer, you're replacing this.team with a new empty ArrayList and then adding a player with this.team.add(player), so only the last added player is in the ArrayList at all times.
What you could do if you really don't want to create the ArrayList in the constructor is check if this.team is null every time you add a player and if the ArrayList is not created or empty, simply create one.
public void addPlayer(Player player) {
if (this.team == null) {
this.team = new ArrayList<Player>();
}
this.team.add(player);
}
Also what's the difference of having it initialized as private ArrayList team = new ArrayList(); before the constructor?
If you're wondering whether the private keyword changes anything, you should read the Java docs on access modifiers: https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
Other than that, initializing before the constructor changes nothing in this case.
I'm trying to figure out why this.team = new ArrayList() have to be in the constructor?
It doesn't, it has to be initialized before it is used. You can initialize it anywhere you want as long as you don't call printPlayer() or addPlayer() before.
Why can't I have this.team = new ArrayList() initialized in the method?
You actually can. See this example:
public void addPlayer(Player player) {
if (team == null) {
team = new ArrayList();
}
team.add(player);
}
public void printPlayers() {
if (team != null) {
for (Player p : team) {
System.out.println(p);
}
}
}
BUT when it's initialized in the method it only list the last given addition to the list. Is it wrong to have it initialized in the method?
No, it's not wrong. It's typically referred to as "lazy initialization" or "on demand" if you do it in the way of the example above.
Also what's the difference of having it initialized as private ArrayList team = new ArrayList(); before the constructor?
Not much, the difference lies in when it is initialized.
public class Example {
public static List<T> myList = new ArrayList<T>(); // this is done first
public static List<T> aList;
public List<T> someList;
static {
// this is also done first (on class load)
aList = new ArrayList<T>();
}
{
// this is done right before the constructor (I believe)
// it is called an 'initialization block'
someList = new ArrayList<T>();
}
public Example() {
// this one you already know...
}
}
I have been coding in Java for about a week now but I am still having issues learning it.
I know that we can create a class and then create instance of it by using the name of a class.
but I have this code which is giving me trouble understanding what is happening here,
This is the file called XMLGettersSetters.java,
public class XMLGettersSetters {
private ArrayList<String> title = new ArrayList<String>();
private ArrayList<String> artist = new ArrayList<String>();
private ArrayList<String> country = new ArrayList<String>();
private ArrayList<String> company = new ArrayList<String>();
private ArrayList<String> price = new ArrayList<String>();
private ArrayList<String> year = new ArrayList<String>();
public ArrayList<String> getCompany() {
return company;
}
public void setCompany(String company) {
this.company.add(company);
Log.i("This is the company:", company);
}
public ArrayList<String> getPrice() {
return price;
}
public void setPrice(String price) {
this.price.add(price);
Log.i("This is the price:", price);
}
public ArrayList<String> getYear() {
return year;
}
public void setYear(String year) {
this.year.add(year);
Log.i("This is the year:", year);
}
public ArrayList<String> getTitle() {
return title;
}
public void setTitle(String title) {
this.title.add(title);
Log.i("This is the title:", title);
}
public ArrayList<String> getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist.add(artist);
Log.i("This is the artist:", artist);
}
public ArrayList<String> getCountry() {
return country;
}
public void setCountry(String country) {
this.country.add(country);
Log.i("This is the country:", country);
}
}
Now I can create object of this class like this,
XMLGettersSetters myObject = new XMLGettersSetters();
but from the website where I am learning this code, they have created the objects like this,
public static XMLGettersSetters data = null;
How come the object is declared static ? what does the above code even mean.
Shouldn't it just be,
XMLGettersSetters data = null;
From what I know, when we declare a variable as static then we donot need to instantiate a class to use a static variable from that class.
One more question,
public static XMLGettersSetters getXMLData() {
return data;
}
I have no idea what happened in the above code,
first the object is instantiated as static then instead of giving object a name, a function is given instead which is getXMLData().
And the return type is data
Now about the code below,
public static void setXMLData(XMLGettersSetters data) {
XMLHandler.data = data;
}
A method is created with XMLGettersSetters object as an argument, but what about XMLHandler.data ?
What is it ? shouldn't it be this.data ?
They probably created the object static because they want it to be global. For example, anywhere in the code you will be able to call XMLHandler.data. (I'm supposing here the class in which is created the data variable is XMLHandler because it is used in the setter method..
If it would simply be XMLGettersSetters data = null; instead of static... then it could not be accessed from anywhere in the code.
As for the XMLHandler.data used instead of this.data you have to know that by convention, most of the people specify the class name before the object they are accessing when accessing a static variable.
Static is a field, not an object. Static fields are per class, shared by all code that have access to this field. They are initialized only once, when the class is first loaded. Usual fields (without static) are per object instance. They are initialized when the object instance is created.
In Java, you can assign the value in the same sentence where you declare the variable:
int x = 2;
Object y = new Object().
The object is instantiated, but then placed into a static variable. This means that you always access the same instance of the XMLGettersAndSetters.
As the methods are static you have to refer to a static variable rather than this.data which refers to the variable in the current instance.
I want to make a program to create people and to show a list of such persons, but do not know if I am doing well and neither logic using "arraylist" to print the results anyone can help me? Thank you very much.
package person;
import java.util.*;
public class Person {
public int Id;
public String Name;
public boolean Show;
public ArrayList people;
public Person(
int identificator,
String thename,
boolean showornot
){
this.Id = identificator;
this.Name = thename;
this.Show = showornot;
}
public void InsertPerson(Person person, ArrayList list){
this.people = list;
list.add(person);
}
}
The main:
package person;
import java.util.*;
public class Trying {
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
Scanner stdin2 = new Scanner(System.in);
Scanner stdin3 = new Scanner(System.in);
Scanner stdin4 = new Scanner(System.in);
ArrayList list_of_people;
list_of_people = new ArrayList();
int option = 0;
int identificador = 0;
String name = "";
boolean show = true;
name = “Toni”;
Person person1 = new Person(identificador, name, true);
person1.InsertPerson (person1, list_of_people);
Iterator ite = list_of_people.iterator();
while(ite.hasNext()){
System.out.println(list_of_people);
}
}
Thanks!
Problem: You are creating the arraylist "people" as a property of each "person" (Saying, each person has a list of people)
Quickfix:
Move public ArrayList people; to your Trying class.
Move public void InsertPerson(Person person, ArrayList list) to your Trying class as well.
Better fix:
I recommend using a PeopleManager class - which contains the arraylist "people" and the InsertPerson method. Then, you use the PeopleManager in Trying to build your people list.
public class PersonManager
{
ArrayList<Person> people;
public PersonManager()
{
people = new ArrayList<Person>();
}
public void InsertPerson(Person person)
{
people.add(person);
}
}
Then, you can remove the arraylist from Person, and the method InsertPerson from Person. You'll need to create a PersonManager in your Trying class.
public ArrayList people; does not belong in the Person class. I would suggest using it your client code (the Trying class) or creating a class People that inherits from ArrayList. You can then add a InsertPerson function to that class if you wish.
I would also suggest using a ArrayList for your collection rather than an ArrayList. See a generic collections tutorial here. You should also create getter/setter moethods instead of using public fields.
So, your classes would be:
public class Person { // ...
public class People extends ArrayList<Person> {
public void InsertPerson(Person person) {
this.add(person);
}
// ...
What everyone else is saying is true, but I think theoretically your code should still work. There is a problem with this line however...
while(ite.hasNext()){
System.out.println(list_of_people);
}
You are outputting the whole list every iteration and probably infinite looping. Change it to something like this...
while(ite.hasNext()){
Person curPerson = (Person)ite.next();
System.out.println(curPerson.Name);
}
A slightly more elegant solution is to ditch the iterator for a foreach loop...
for (Person person : list_of_people) {
System.out.println(person.Name);
}
So basically I have this constructor for the class League:
import java.util.*;
public class League {
private String name;
private List<Team> teamList;
public League(String name) {
List<String> teamNames = new LinkedList<String>(Company.teamList);
Collections.shuffle(teamNames);
teamNames.subList(0, 5);
for(int i = 0; i < teamNames.size(); i++){
teamList.add(new Team(teamNames.get(i)));
}
}
}
The class Company happens to have a Set called teamList.
When I call on System.out.println(teamNames.get(i)) it shows me the content so obviously the elements of the set are there, however when I try to create a new Team object based on the elements of the list of Strings, it gives me a NullPointerException. I don't know why is that? Help?
Here is the code for the Team class in case you need it:
import java.util.HashMap;
import java.util.Map;
public class Team {
protected Map<Integer, Player> teamPlayerMap;
private String teamName;
public Team(String name) {
teamPlayerMap = new HashMap<Integer, Player>();
teamName = name;
}
public String getTeamName() {
return teamName;
}
}
I think the problem is here:
private List<Team> teamList;
public League(String name) {
// etc...
for(int i = 0; i < teamNames.size(); i++) {
teamList.add(new Team(teamNames.get(i))); // This will throw!
}
}
You need to create an instance of a class that implements List<Team> and assign it to teamList. You haven't done this so it will throw a NullPointerException when you call teamList.add(...).
The fix is to write this instead:
private List<Team> teamList = new ArrayList<Team>();
You must initialize teamList:
private List<Team> teamList = new ArrayList<Team>();
Problem is because you not create instance of teamList I think.