Apologies in advance, I am new to Java and I am using someone else's code for the most part so please bear with me. I have looked around but couldn't find anything to help my problem
I've retrieved an ArrayList from a method and then I've attempted to write a foreach loop to retrieve a specific piece of data from what is an 'Observation' below.
For whatever reason it won't allow me to retrieve any of the data stored inside an observation when accessing through the ArrayList.
ArrayList<Observation>[] npcPositions = stateObs.getNPCPositions();
Vector2d playerPosition = stateObs.getAvatarPosition();
int npcCount = npcPositions.length;
for (int i = 0; i <= npcCount; i++)
{
if (playerPosition.x == npcPositions[i].position)
{
}
}
position being a value within the Observation but I get the error that it cannot be resolved or is not a field. Part of the observation class is below and I can not access any of these variables doing what I'm currently doing.
public class Observation implements Comparable<Observation>
{
/**
* Category of this observation (static, resource, npc, etc.).
*/
public int category;
/**
* Type of sprite of this observation.
*/
public int itype;
/**
* unique ID for this observation
*/
public int obsID;
/**
* Position of the observation.
*/
public Vector2d position;
/**
* Reference to the position used for comparing this
* observation with others.
*/
public Vector2d reference;
So what do I need to use to access those variables. I noticed that I have to use [] when I want to store data from stateObs.getNPCPositions and that seems to be the reason why other examples weren't working for me but I am unsure on how to fix it.
UPDATE
The original issue seems to be fixed, however when attempting to retrieve the length of the ArrayList, I get nullpointerexception. How can I get the number of items to be able to run through them in the loop each time.
UPDATE #2
/**
* Returns a list of observations of NPC in the game. As there can be
* NPCs of different type, each entry in the array corresponds to a sprite type.
* Every ArrayList contains a list of objects of type Observation.
* Each Observation holds the position, unique id and
* sprite id of that particular sprite.
*
* #return Observations of NPCs in the game.
*/
public ArrayList<Observation>[] getNPCPositions()
{
return model.getNPCPositions(null);
}
/**
* Returns a list of observations of NPC in the game. As there can be
* NPCs of different type, each entry in the array corresponds to a sprite type.
* Every ArrayList contains a list of objects of type Observation, ordered asc. by
* distance to the reference passed. Each Observation holds the position, sprite type id and
* sprite id of that particular sprite.
*
* #param reference Reference position to use when sorting this array,
* by ascending distance to this point.
* #return Observations of NPCs in the game.
*/
public ArrayList<Observation>[] getNPCPositions(Vector2d reference)
{
return model.getNPCPositions(reference);
}
This:
ArrayList<Observation>[] npcPositions = stateObs.getNPCPositions();
is getting an array of ArrayList. You can get a single ArrayList from index i of the array using:
ArrayList<Observation> list = npcPositions[i];
You can get the Observation at index j of your list using:
Observation obs = list.get(j);
Or you can use them in combination:
Observation obs = npcPositions[i].get(j);
In line:
npcPositions[i].position
Is an array of ArrayList which does not have any property position. Possibly you would try:
npcPositions[i].get(0).position
Edited:
As you said that this line gives NPE:
int npcCount = npcPositions.length;// possibly npcPositions is null
Below line is executed to get the array list:
public ArrayList<Observation>[] getNPCPositions()
{
return model.getNPCPositions(null);//<-- note this, possibly model is also null
}
I am not sure what you are doing in the first two lines of your code, but assumming that what you are doing is correct then the problem lies with your if statement. You are trying to test if a Vector2D.x is equal to a Vector2D which can never happen. try doing this
for(int i = 0; i < npcCount; < i++)
{
if(playerPosition == npcPositions.get(i).position)
{
//do something here
}
}
or you can try this
for(int i = 0; i < npcCount; < i++)
{
if(playerPosition.x == npcPositions.get(i).position.x)
{
//do something here
}
}
Related
I need to add an Object to an ordered ArrayList depending on an attribute inside of the Object. I know how to use the .add method to add the object but I don't know how to search for the right place for it using the compareTo() method. And also I need to remove an Object from the ArrayList if the Object contains a certain String but I cant figure out how to access the Object attributes from the ArrayList.
Realtor Object
/**
* Constructor for Realtor object using parameter
* #param readData - array of data from line
*/
public Realtor(String[]readData){
licenseNumber = readData[2];
firstName = readData[3];
lastName = readData[4];
phoneNumber = readData[5];
commission = Double.parseDouble(readData[6]);
}
RealtorLogImpl
public class RealtorLogImpl {
private ArrayList<Realtor> realtorList;
/**
* Add Realtor object to ordered list
* #param obj - Realtor object
*/
public void add(Realtor obj){
//needs to be added into correct place depending on Realtor licenseNumber
realtorList.add(obj);
}
/**
* Delete Realtor object from list if license matches
* and return true if successful
* #param license
* #return
*/
public boolean remove (String license){
//need to remove Realtor with specific licenseNumber and return true if successful
}
I'm assuming you are using java 8. Some of these things have not been implemented in java 7 so keep that in mind.
First, to remove the items I would recommend using the removeif() method on the arraylist. This takes a lambda expression which could be something like x -> x.getString().equals("someString").
Second, You could add the object to the array then simply sort the array afterwards. You would just have to write a comparator to sort it by.
Here is some basic code; I have no compiler here, so you might find small errors/typos.
I'm sure there are better classes you can use instead of managing your own ordered list.
To insert:
public bool add(Realtor obj) {
int idx = 0;
for (Realtor s : realtorList) {
if (s.licenseNumber.equals(item.licenseNumber)) {
return false; // Already there
}
if (s.licenseNumber.compareTo(item.licenseNumber) > 0) {
orderedList.add(idx, item);
return true; // Inserted
}
idx++;
}
orderedList.add(item);
return true; // Appended
}
To delete:
public bool deleteItem(String license) {
int idx = 0;
for (Realtor s : realtorList) {
if (s.licenseNumber.equals(license)) {
realtorList.remove(idx);
return true; // Removed
}
}
return false; // Not found
}
To answer your question check the following snippet (requires Java 8) and adapt on your demand:
public static void main(String[] args) {
final List<String> list = new ArrayList<>();
list.add("Element 1");
list.add("Element 2");
list.add("Element 3");
/*
* Insert at a specific position (add "Element 2.5" between "Element 2" and "Element 3")
*/
Optional<String> elementToInsertAfter = list.stream().filter(element -> element.equals("Element 2")).findFirst();
if(elementToInsertAfter.isPresent()) {
list.set(list.indexOf(elementToInsertAfter.get()) + 1, "Element 2.5");
}
/*
* Remove a particular element (in this case where name equals "Element 2")
*/
list.removeIf(element -> element.equals("Element 2"));
}
#add(element) just adds an element to the list. In case of an ArrayList it's added at the end. If you want to insert an element at a particular position you need to use #set(index,element)
But instead of inserting your element at a particular position manually you should maybe use a comparator instead. See java.util.List.sort(Comparator<? super E> e)
(EDITED CODE)
I am having a bit of an issue I hope I can get some help on. Here are my conditions:
You are developing a program to keep track of team standings in a league. When a game is played, the winning team (the team with the higher score) gets 2 points and the losing team gets no points. If there is a tie, both teams get 1 point. The order of the standings must be adjusted whenever the results of a game between two teams are reported. The following class records the results of one game.
public class GameResult
{
public String homeTeam() // name of home team
{ /* code not shown */ }
public String awayTeam() // name of away team
{ /* code not shown */ }
public int homeScore() // score for home team
{ /* code not shown */ }
public int awayScore() // score for away team
{ /* code not shown */ }
// instance variables, constructors, and other methods not shown
}
The information for each team is stored by an instance of the class TeamInfo whose partial definition is below.
public class TeamInfo
{
public String teamName()
{ /* code not shown */ }
public void increasePoints(int points)
{ /* code not shown */ }
public int points()
{ /* code not shown */ }
// instance variables, constructors, and other methods not shown
}
The class TeamStandings stores information on the team standings. A partial declaration is shown below.
public class TeamStandings
{
TeamInfo[] standings; // maintained in decreasing order by points,
// teams with equal points can be in any order
public void recordGameResult(GameResult result)
{ /* to be completed as part (c) */ }
private int teamIndex(String name)
{ /* to be completed as part (a) */ }
private void adjust(int index, int points)
{ /* to be completed as part (B)/> */ }
// constructors and other methods not shown
}
And here is the actual question:
Write the method adjust. The method adjust should increment the team points for the team found at the index position in standings by the amount given by the parameter points. In addition, the position of the team found at index in standings should be changed to maintain standings in decreasing order by points; teams for which points are equal can appear in any order.
And here is what I have so far:
private void adjust(int index, int points)
{
int Score[] = new int[standings.length]
for ( int i=0; i < standings.length; i++)
{
Score[i] = points;
Arrays.sort(Score);
}
}
I realize this is very wrong and need a little guidance to solve this. Thank you!
Something like this should work:
private void adjust(int index, int points) {
// increase points of winning team
TeamInfo curr = standings[index];
curr.increasePoints(points);
// get the new score of the winning team
int points = curr.points();
// perform an insertion sort on the modified portion
int i = index;
while (i > 0 && standings[i-1].points() < points) {
// shift teams with lower scores rightwards
standings[i] = standings[i-1];
i--;
}
standings[i] = curr;
}
Basically, it just gets the winning team (curr) at the specified index parameter and increments its points. Since the list must be ordered by team points in descending order, just insert the team in their correct position after adjusting the points.
problem is :
for ( int i=0; i <= standings.length; i++)//here index out of bounds
{
Score[i] = index, points;//here
}
write like :
for ( int i=0; i <standings.length; i++)
{
Score[i] = points;
}
Here's how to adjust the points for a team in the standings.
private void adjust(int index, int points)
{
/* 'index' is by definition an index into the standings array
* 'points' is by definition how many points to give to the team at 'index'
* each TeamInfo object has a method called increasePoints()
* therefore, to increase the number of points for a team in the standings... */
standings[index].increasePoints(points);
}
make sense?
Now, to sort the standings in order of point value, I imagine the exercise wants you to do something that uses TeamStandings.teamIndex() in combination with the other methods in your TeamInfo class. But since the code is either hidden or not written yet, I can't do much more.
first off this is an assignment so I'm more looking for help then coded answers (don't want to cheat!). My assignment is to create a program that processes a train/railway network of stations. The section i'm stuck on adds the stations, their connections, and returns these connections as an Array List of Strings. I've included below the code I have so far, and also an extract from the assignment (related to the section I'm on now). I've been struggling with this bit all weekend, so any help would be hugely appreciated.
It's only the implementation of the interface I need to edit, the "MyNetwork" class. I just feel I've been going in circles, and may not have even gotten off on the right foot?
From the assignment;
Create a class MyNetwork that implements the Network interface.
The getConnections method of this class should return an array containing only those stations directly connected to the fromStation argument.
Hint 1: you can do this using a HashMap, with the keys being Strings (representing stations) and the values being ArrayLists of Strings (representing the stations to which there is a direct connection).
Hint 2: Although the getConnections method returns an array of Strings, it would be better for the values in the HashMap to be ArrayLists of Strings
The Interface;
public interface Network {
/**
* Add a station to the network.
* #param station The station to be added.
*/
public void addStation(String station);
/**
* Add a direct connection from one station to another.
* #pre both fromStation and toStation have already been added by the method
* addStation.
* #param fromStation The station from which the connection begins.
* #param toStation The station at which the connection ends.
*/
public void addConnection(String fromStation, String toStation);
/**
* Get a list of all stations directly connected to a given station.
* #pre fromStation has been added to the network by the method addStation.
* #param fromStation
* #return A list of all the stations to which there is a direct connection
* from fromStation.
*/
public String[] getConnections(String fromStation);
/**
* Search for a station in the network.
* #param station Station to be searched for,
* #return true if the Station exists in the network, false otherwise.
*/
public boolean hasStation(String station);
/**
* Get all stations in the network.
* #return An array containing all the stations in the network, with no
* duplicates.
*/
public String[] getStations();
The Implementation:
public class MyNetwork implements Network {
#Override
public void addStation(String station) {
ArrayList<String> Stations = new ArrayList<>();
Stations.add(station);
}
#Override
public void addConnection(String fromStation, String toStation) {
Map<String,String> Connections = new HashMap<>();
Connections.put(fromStation, toStation);
}
#Override
public String[] getConnections(String fromStation) {
return null; // dummy value!
}
#Override
public boolean hasStation(String station) {
return false; // dummy value!
}
#Override
public String[] getStations() {
return null; // dummy value!
}
}
Your network needs to have a state, using one or several instance field(s).
As is, it doesn't have any state. Each method creates a local variable of type List or Map, adds something to this List or Map, and returns. So the List or Map directly goes out of scope and is garbage collected.
private Map<String, List<String>> stations = new HashMap<>();
// now all your methods should use the above map.
See http://docs.oracle.com/javase/tutorial/java/javaOO/classes.html
I have been trying to figure out how to add runner information into an array of runner information. It should contain at most 100 runners.
This is part of a larger project that must fulfill these requirements:
Operations (methods):
• A constructor that takes in a race name and distance.
• Getters and setters for both the name and distance instance variables.
• Method to return the count of the number of RunnerResult objects added to the array.
• Method to add a RunnerResult to the array (given an instance of Runner and the runner’s finishing time).
• Methods to get a RunnerResult object; one that takes in the position in which the RunnerResult was added (to directly access the object from the array) and one that takes in a runner name (to use to search for the matching runner). The first runner’s index is 0, the second is 1, etc.
• A method with conditional logic to give a count of all runners for a certain category (youth, adult, senior, male, female, all) triggered by a flag passed in as a whole number (1, 2, 3, 4, 5, 6, respectively, implemented as public constants). A similar method provides the average race result (time to finish race) for each potential category.
• A method with conditional logic finds runners with a race time less than the specified minutes per mile. For example, find all runners who finished the race with a time of less than 8 minutes per mile.
• A toString method that simply gives the race name, race distance, a count of total runners in the race, and the average time of all runners in the race.
So far, this is what I have:
public class Race
{
// instance variables
private String name;
private double distance;
private int nextPos;
private RunnerResult [] results;
// public constants
/**
* Flag to signify YOUTH.
*/
public static final int YOUTH = 1;
/**
* Flag to signify ADULT.
*/
public static final int ADULT = 2;
/**
* Flag to signify SENIOR.
*/
public static final int SENIOR = 3;
/**
* Flag to signify MALE.
*/
public static final int MALE = 4;
/**
* Flag to signify FEMALE.
*/
public static final int FEMALE = 5;
/**
* Flag to signify ALL.
*/
public static final int ALL = 6;
/**
* Array limit.
*/
public static final int MAX_COUNT = 100;
/**
* Constructor for objects of class Race.
*
* #param inName the race name.
* #param inDist the distance of the race.
*
*/
public Race(String inName, double inDist)
{
// initialize the instance variables and
// empty array of results, initalize nextPos
this.name = inName;
this.distance = inDist;
RunnerResult[] results = new RunnerResult[100];
}
/**
* Set the race Name.
*
* #param inName the race name.
*
*/
public void setName(String inName)
{
this.name = inName;
}
/**
* Get the race Name.
*
* #return String The race name.
*
*/
public String getName()
{
return this.name;
}
/**
* Set the race distance.
*
* #param inDist the distance of the Race.
*
*/
public void setDist(double inDist)
{
this.distance = inDist;
}
/**
* Get the race distance.
*
* #return double the distance of the race.
*
*/
public double getDist()
{
return this.distance;
}
/**
* Add a runner to the results
* (runners are NOT entered in order of finish).
*
* #param inChip the runner's chip id.
* #param inRunner a Runner object.
* #param inStart the start time for the runner.
* #param inEnd the end time for the runner.
*
*/
public void addRunner(String inChip, Runner inRunner, Time inStart, Time inEnd)
{
if (this.nextPos < MAX_COUNT)
{
// set the instance field element to a "copy" of passed-in object
// add to array, increment counter
for(int i = 0; i < results.length; i++);
{
RunnerResult[] results = { copyinChip, copyinRunner, copyinStart,
copyinEnd };
i++;
}
}
}
}
I just cannot figure out how to get these values into the array. (I get an incompatible type error. Any input would be greatly appreciated.
two things here.
1.) when you re-declare results, you are not referencing the same object that you declare as a field, but an entirely new object that then has no purpose, because it only lives within addRunner.
2.) When you assign results = { ---, ---, ---, ---}; You aren't adding a new runner to the array. Rather, you are reassigning the entire array every single time you do that loop. You would want to create a new RunnerResult object, add the necessary data to it, and then put that at results[];
An example here:
public void addRunner(String inChip, Runner inRunner, Time inStart, Time inEnd)
{
if (this.nextPos < MAX_COUNT)
{
// set the instance field element to a "copy" of passed-in object
// add to array, increment counter
for(int i = 0; i < results.length; i++);
{
results[i] = new RunnerResult(<your params>);
}
}
}
I have the following code. However I am doubting about if it is the right way to implement it or not.
What I mean is: in the collection framework there are many data structures to use and creating the class (MemberList) to manage the aggregations of many members can be implemented using ArrayList, LinkedList, priority queue ...
I would like to use a data structure that fits with my needs, and that has the least Big O possible when it comes to searching, sorting, deleting, adding, modifying and deleting.
public class MemberList{
/**
*a list of accounts existing in the database
*/
private static List<Member> members = new ArrayList<Member>();
/**
* add a member to our member list
* #param m the member to be added
*/
public static void Add(Member m)
{
members.add(m);
/**
* delete a member from our member list
* #param m the member to be deleted
*/
public static void Delete(Member m)
{
Iterator<Member> it = members.iterator();
while(it.hasNext())
{
if(m.equals(it.next()))
{
it.remove();
}
}
}
/**
* Search for a specific member in the member list
* #param m the member that needs to be found
* #return the reference of the object Member
* #throws UserNotFoundExeption whether the member was not found in the list
*/
public static Member Search (Member m) throws UserNotFoundExeption
{
Iterator<Member> it = members.iterator();
while(it.hasNext())
{
if(m.equals(it.next()))
{
return it.next();
}else{
UserNotFoundExeption ex = new UserNotFoundExeption(it.next().getUsername());
throw ex;
}
}
return null;
}
/**
* The login method enables checking whether the login was made successfully or not. if not, it can throw two
* exceptions to handle the errors
* #param member
* #return
* #throws UserNotFoundExeption
* #throws FailedLoginException
*/
public static boolean login (Member m)
throws UserNotFoundExeption,FailedLoginException {
try{
Member member = Search(m);
if (!m.authenticate(member.getPassword()))
{
FailedLoginException ex2 = new FailedLoginException (member.getPassword());
throw ex2;
}
else
{
return true;
}
}catch(UserNotFoundExeption ex){
throw ex;
}
}
/**
* this behavior modify attributes of the corresponding class
* #param <T> this generic helps to accept any type of parameter change, hence we can change any type
* #param m this is the member that need to change his information
* #param choice the choice of which information to change
* #param change the new change on the member attribute
* #throws UserNotFoundExeption
*/
public static <T> void Modify(Member m, int choice, T change) throws UserNotFoundExeption
{
try{
Member member = Search(m);
switch(choice)
{
case 1:
member.setUsername((String)change);
break;
case 2:
member.setPassword((String)change);
break;
case 3:
member.setCommunity((Community)change);
break;
}
}catch(UserNotFoundExeption ex){
throw ex;
}
}
/**
* display the member list objects information
*/
public static void Display()
{
Iterator<Member> it = members.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
/**
* Sort objects in the list
*/
public static void Sort()
{
Iterator<Member> it = members.iterator();
Member[] Members_Array = members.toArray(new Member[members.size()]);
Member temp;
for(int i = 0; i<members.size(); i++)
{
for(int j = 0; j < members.size() - (i+1); j++)
{
if(Members_Array[j].compareTo(Members_Array[j+1]) > 0)
{
temp = Members_Array[j];
Members_Array[j] = Members_Array[j+1];
Members_Array[j+1] = temp;
}
}
}
}
}
Thank you!
This question is too broad, and "the right way to use collections in Java" is also a philosophical question, so it cannot be scientifically answered.
Specifically to your case, depending on the pool of your members, you probably don't want to iterate over them when you need to pull a member out. I would recommend you use something like a HashMap<String,Member>, where each member has an identifiable unique key (a username for instance). This will grant you O(1) access speed and allow you to iterate when you need it using .values().
You can use a HashMap like so:
// This is how you create a hash map:
HashMap<String,Member> members = new HashMap<String,Member>();
// This is how you add an object to it. It is slower than lists,
// but since reading happens far often, it pays off.
members.put("ben", new Member());
// This is how you access an object in the hash map.
// Accessing a hash map is O(1).
Member member = members.get("ben");
// This is how you remove an object from the hash map.
// Removing an object is also O(1)
members.remove("ben");
// Hash maps are also iterable
for(Member member : members.values()) {
}
I would use array list if you dont want to use JDBC.
But later if your project going to growe, you have to use JDBC.