I have a problem I have been working on for a long time and I cannot seem to figure it out.
I need to make a method called shownodesandlinks in the GraphData class or the Node class and then print out the arraylist in the graphdata class in the Main class.
How do I do that? I can print the method but it is only spitting out "at ruttsokning.Node.addNeighbour(Node.java:76)" and not the data from the table I need. Here is my code, I have currently 3 classes.
Main class
package ruttsokning;
import ruttsokning.GraphData;
import java.io.*;
import ruttsokning.Node;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
GraphData data = new GraphData();
ArrayList<Node> graph = data.createGraph();
data.shownodesandlinks(graph);
}
}
GraphData class
package ruttsokning;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import ruttsokning.Node;
public class GraphData {
public ArrayList<Node> createGraph() {
LinkedHashMap<String,Node> nodes = new LinkedHashMap<>();
nodes.put("bole", new Node("Böle bibliotek", 60.2008, 24.9359));
nodes.put("vall", new Node("Vallgårds bibliotek", 60.1923, 24.9626));
nodes.put("berg", new Node("Berghälls bibliotek", 60.1837, 24.9536));
nodes.put("tolo", new Node("Tölö bibliotek", 60.1833, 24.9175));
nodes.put("oodi", new Node("Centrumbiblioteket Ode", 60.174, 24.9382));
nodes.put("rich", new Node("Richardsgatans bibliotek", 60.1663, 24.9468));
nodes.put("bush", new Node("Busholmens bibliotek", 60.16, 24.9209));
HashMap<String,String[]> neighbours = new HashMap<>();
neighbours.put("bole", new String[]{"tolo", "berg"});
neighbours.put("vall", new String[]{"berg"});
neighbours.put("berg", new String[]{"bole", "vall", "tolo", "oodi"});
neighbours.put("tolo", new String[]{"bole", "berg", "oodi", "bush"});
neighbours.put("oodi", new String[]{"tolo", "berg", "rich"});
neighbours.put("rich", new String[]{"oodi", "bush"});
neighbours.put("bush", new String[]{"tolo", "rich"});
ArrayList<Node> graph = new ArrayList<>();
for (String id : nodes.keySet()) {
nodes.get(id).setId(id);
for (String neighbor : neighbours.get(id)) {
nodes.get(id).addNeighbour(nodes.get(neighbor));
}
graph.add(nodes.get(id));
}
return graph;
}
public void shownodesandlinks(ArrayList<Node> graph) {
for (Node node : graph) {
System.out.println(node);
// print node here
}
}
}
Node class
package ruttsokning;
import java.util.ArrayList;
public class Node{
static String name;
private static double latitude;
private static double longitude;
static ArrayList<Node> neighbours;
private Node next;
public Node(String name, double latitude, double longitude)
{
setName(name);
setLatitude(latitude);
setLongitude(longitude);
setNext(next);
}
public double getLatitude()
{
return latitude;
}
public double getLongitude()
{
return longitude;
}
public static String getName()
{
return name;
}
public ArrayList<Node> getNeighbours()
{
return neighbours;
}
public void setName(String name)
{
Node.name = name;
}
public void setLatitude(double latitude)
{
Node.latitude = latitude;
}
public void setLongitude(double longitude)
{
Node.longitude = longitude;
}
public void setNext(Node next)
{
this.next = next;
}
public void addNeighbour(Node neighbours)
{
neighbours.addNeighbour(neighbours);
}
public void setId(String id) {
}
}
at ruttsokning.Node.addNeighbour(Node.java:76) is part of a stack trace, a multi-line message that Java prints whenever your program has crashed. The message contains information about what kind of error has occurred, as well as which part of the system caused the crash.
In this case, the problem was presumably a NullPointerException in the method addNeighbour. This is due to you trying to add data into the list named neighbours, except that list is never initialized. It's always null, causing this error.
In the class GraphData, I can see that you have another list named neighbours that you do initialize with data. These are however completely separate things that happen to share a name.
The simplest solution seems to be to have GraphData make use of the other list instead of creating its own. This could be done by replacing the existing initialization with this:
Node.neighbours = new HashMap<>();
Node.neighbours.put("bole", new String[]{"tolo", "berg"});
Node.neighbours.put("vall", new String[]{"berg"});
Node.neighbours.put("berg", new String[]{"bole", "vall", "tolo", "oodi"});
Node.neighbours.put("tolo", new String[]{"bole", "berg", "oodi", "bush"});
Node.neighbours.put("oodi", new String[]{"tolo", "berg", "rich"});
Node.neighbours.put("rich", new String[]{"oodi", "bush"});
Node.neighbours.put("bush", new String[]{"tolo", "rich"});
...and also update the reference to neighbours in the for loop to instead use Node.neighbours.
This method is causing (the first) problem:
public void addNeighbour(Node neighbours)
{
neighbours.addNeighbour(neighbours);
}
above code is not a correction, just to show the problem
well called, addNeighbour will call the method addNeighbour (same method) of neighbours. This will again try to call addNeighbour, which will again call addNeighbour. ...
These chain will only terminate after the stack overflows (StackOverflowException, basically out of memory).
Probably it was meant to add the node to the list, that is
public void addNeighbour(Node newNeighbour)
{
neighbours.add(newNeighbour);
}
but here we see the next problem - the list neighbours is not initialized and is static (urgent to learn the difference between static and non-static members!)
The list must be initialized
in its declaration:
ArrayList<Node> neighbours = new Arraylist<>();
or constructor:
neighbours = new Arraylist<>();
Fields being static:
static fields are not associated to an instance, but to the class. In other words there is only one value (memory position), no matter how many instances were created. In that code all Nodes will share the same name, coordinates and neighbours!
Simple example (how not to do it):
class Node {
static String name;
Node(String newName);
name = newName;
}
}
the following code will print second, despite n1 was created with first
Node n1 = new Node("first");
Node n2 = new Node("second");
System.out.println(n1.name);
new Node("second") is setting the field name, since it is static - there is only one field - n1 is also using the same name, so it returns the last value set.
Solution: do remove static from all fields of Node, these should be instance variables, not class variables. (same for getters and setters for these fields)
pretty new to Java,
I have a Graph of JGraphT with Employees as nodes and an Interface called "FeatureEdge" as edges.
I create some edges by reading through a database to connect my employees.
Now I want to export my edges by edge-type ( Location- or Interestedge ) but I have no clue how to know which of my List<FeatureEdge> list edges is of which implemented type.
Any suggestions, how I can get a type ? In C++ I would dynamic_cast every edge of my list to both types and check which one would work, but I don't know how to do it in Java,
Graph:
public MultiGraph<Employee, FeatureEdge> graph = new Multigraph<>(FeatureEdge.class);
Interface:
public interface FeatureEdge {}
Implementations:
public class LocationEdge implements FeatureEdge {
private String location;
public LocationEdge(String location){
this.location = location;
}
public String getLocation(){
return this.location;
}
}
public class InterestEdge implements FeatureEdge {
private int interestStrength;
public InterestEdge(int strength) {
this.interestStrength = strength;
}
public int getInterestStrength() {
return this.interestStrength;
}
}
Just use a getClass() method:
List<Integer> linkedList = new LinkedList<Integer>();
List<Integer> arrayList = new ArrayList<Integer>();
for (List<?> list : Arrays.asList(linkedList, arrayList)) {
System.out.println(list.getClass());
}
will print
class java.util.LinkedList
class java.util.ArrayList
I have created a class like this, which contains a bunch of arraylist as you can see. I've been setting the array with the methods add.. and then retrieving it with get.., when i tried to System.out.println numberofcitizen for example it is returning 0. Note that i have instantiated the class in another class to set the values.
public int numberOfCitizen;
private final ArrayList<Integer> citizenid = new ArrayList<>();
private final ArrayList<String> citizenName = new ArrayList<>();
private final ArrayList<Integer> citizenWaste = new ArrayList<>();
private final ArrayList<Float> longitude = new ArrayList<>();
private final ArrayList<Float> latitude = new ArrayList<>();
private final ArrayList<String> address = new ArrayList<>();
public void working() {
System.out.println("executing fine");
}
public void setnoOfcit(int number) {
this.numberOfCitizen = number;
}
public int getnumber() {
return this.numberOfCitizen;
}
public void addCitizenId(int citizen) {
citizenid.add(citizen);
}
public int getCitizenid(int i) {
int citId = citizenid.get(i);
return citId;
}
public void addCitizenName(String citizenname) {
citizenName.add(citizenname);
}
public String getCitizenName(int i) {
return citizenName.get(i);
}
public void addCitizenWaste(int waste) {
citizenWaste.add(waste);
}
public int getCitizenWaste(int i) {
return citizenWaste.get(i);
}
public void addLatitude(float lat) {
latitude.add(lat);
}
public float getLat(int i) {
return latitude.get(i);
}
public void addlng(float lng) {
longitude.add(lng);
}
public float getlng(int i) {
return longitude.get(i);
}
com.graphhopper.jsprit.core.problem.VehicleRoutingProblem.Builder vrpBuilder = com.graphhopper.jsprit.core.problem.VehicleRoutingProblem.Builder.newInstance();
public void runVPRSolver() {
System.out.println(numberOfCitizen);
System.out.println(getCitizenName(0));
//create a loop to fill parameters
Probable source of problem :
numberOfCitizen is a member attribute that you seem to never change. If you want it to represent the number of elements in your lists, either use citizenName.size() or increment the value of numberOfCitizen in one of the add methods.
Design flaw :
Your design takes for granted that your other class always use that one properly. Anytime you or someone uses that class, he must make sure that he add every single element manually. This adds code that could be grouped inside your class, which would be cleaner and easier to maintain.
So instead of several add method like this :
addCitizenid();
addCitizenName();
addCitizenWaste();
addLongitude();
addLatitude();
addAddress();
Design an other Citizen class which will contain those elements, and use a single list of instances of that class. That way you can use only one method :
private List<Citizen> citizenList = new ArrayList<>();
public void addCitizen(Citizen c) {
/*Add element in your list*/
citizenList.add(c);
}
This programming methodology is called "Encapsulation" which you can read about here
You need to increment numberOfCitizen in your add methods. For example:
public void addCitizenId(int citizen){
citizenid.add(citizen);
numberOfCitizen++;
}
I would also suggest encapsulating your variables into Objects, so create a citizen class:
public class Citizen {
private Integer id;
private Integer name;
private Integer waste;
}
And change your variable to an ArrayList of objects:
ArrayList<Citizen> citizens;
How do I refer to a certain parameter of my Object that is queued up in my list?
We're currently working with lists and Im trying to compare a parameter with a specific parameter of an Object that is in my list. The class list only offers getContent(), but I don't need the object I need the parameter inside the object.
if (answer.equals(a)) {
vocList.getContent(Vocabulary.getGerman());
}
I've got a getter in the class Vocabulary. Vocabulary is queued in my List
Vocabulary class:
public class Vocabulary {
private String deutsch;
private String englisch;
public Vocabulary(String pGerman, String pEnglish)
{
english = pEnglish;
german = pGerman;
}
public String getGerman()
{
return german;
}
public String getEnglish()
{
return english;
}
}
To get the value of an object you need the getter you created in the Vocable class:
vocList.get(i).getGerman(); //i is the index of the object in your list.
So your Vocable class should look like this to actually store the values you create the objects with:
public class Vocable{
private String german;
private String english;
public Vocable(String pGerman, String pEnglish){
english = pEnglish;
german = pGerman;
}
public String getGerman(){
return german;
}
public String getEnglish(){
return english;
}
}
This appears to be a homework question since you say, "We are currently working with lists." So, I'll try to steer you in the right direction without giving the answers away. I also recommend you read the Oracle Java Tutorial on Objects.
Now, to your question: You want to get a handle to the specific Object---once you have a handle for the Object, you can call its instance methods or access its fields' values. For example, suppose I have a Rectangle object:
public class Rectangle {
public int x;
public int y;
public int width;
public int height;
public Rectangle(int x, int y, int width, int height) {
this.X = x;
this.Y = y;
this.width = width;
this.height = height;
}
}
You can use the following code to print create a new Rectangle and then print its fields' values. Notice you have to get the element from the list (using get(0)) before I could access the Rectangle's variables. You have to do the same thing in your code, but it looks like you're using a custom List implementation; So, you'll have to use the getContent method to get a reference to the object.
public class CreateObjectDemo {
public static void main(String[] args) {
//create an ArrayList
static List<Rectangle> rectangleList = new ArrayList<Rectangle>();
//create a rectangle and add it to the array list
Rectangle rect = new Rectangle(50,50,100,75);
rectangleList.add(rect);
printFirstRectangle(rectangleList);
}
/** Prints the first rectangle in the list */
private static void printFirstRectangle(List<Rectangle> rectangles){
if (rectangles.size() > 0){ //if the list has at least one element
//get the handle for the first element---the one at the 0th index
Rectangle firstRect = rectangle.get(0);
//print the result
System.out.printf("First Rectangle, x=%d, y=%d, width=%d, height=%d\n",
firstRect.x,
firstRect.y,
firstRect.width,
firstRect.height);
} else { //if the list is empty
System.out.println("The list is empty.");
}
}
}
I would like to be able to modify the value of a local variable defined in a constructor within the class via the main driver class at some point while running the program. How would I be able to achieve this?
Here is a sample of a constructor that I am using.
public Scale()
{
weight = 0;
unit = "kg";
}
I'd like to modify the value of weight at a point while running the program in the driver.
It sounds like you're wanting to give the class a method that would allow outside code to be able to change or "mutate" the state of the fields of the class. Such "mutator" methods are commonly used in Java, such as "setter" methods. Here, public void setWeight(int weight):
public void setWeight(int weight) {
this.weight = weight;
}
The best way to allow that would probably be through a method. It could be something as straightforward as setWeight(), or something more complicated like a method for adding items to the scale...
public class Scale {
private float weight = 0;
private String unit = "kg";
public void setWeight(float weight) {
this.weight = weight;
}
public void addItem(Item i) { // Assumes that Item is an interface defined somewhere else...
this.weight += i.getWeight();
}
public static void main(String[] args) {
Scale s = new Scale();
s.setWeight(4.0F); // sets the weight to 4kg
s.addItem(new Item() {
#Override
public float getWeight() {
return 2.0F;
}
}); // Adds 2kg to the previous 4kg -- total of 6kg
}
}