I have got a txt file (representing nodes and cost in the graph) which has the following format:
A B 2
A C 3
A D 4
B C 2 . . .
I have got a class called Node to represent the above data. Following is my Node class
class Node{
Node leftchild;
Node rightchild;
int cost;
public Node(Node firstchild, Node secondchild, int cost){
this.leftchild = firstchild;
this.rightchild = secondchild;
this.cost = cost;
}
public Node(Node firstchild, Node secondchild) {
this.leftchild = firstchild;
this.rightchild = secondchild;
}
public ArrayList<Node> getChildren(){
ArrayList<Node> childNodes = new ArrayList<Node>();
if(this.leftchild != null)
{
childNodes.add(leftchild);
}
if(this.rightchild != null)
{
childNodes.add(rightchild);
}
return childNodes;
}
public boolean removeChild(Node n){
return false;
}
}
I would now like to read the data (above mentioned format) from a file and store it in a three dimensional array like following
[A] [B] [2]
[A] [C] [3]
.. So on
I have got the following method to read the data from the file and storing it in an array, but I am getting an error while adding the tokens to the arraylist.
My error is saying as: Incompatible types: String cannot be converted to Node.
I am not sure how to fix this. Any kind of help is much appreciated. Thanks.
public Node[][][] getNodes(File file) throws IOException {
FileReader inputHeuristic = new FileReader(file);
BufferedReader bufferReader = new BufferedReader(inputHeuristic);
String line;
List list = new ArrayList();
while ((line = bufferReader.readLine()) != null) {
String[] tokens = line.split(" ");
list.add(new Node(tokens[0], tokens[1], tokens[2]));
}
bufferReader.close();
return list.toArray(new Node[list.size()]); // converting list to array
}
What you are trying to do does not make much sense. You cannot change something that is a type String to a class object. Either you need to change what is being passed to the constructor or you need to change the type of the instance variables to String.
Personally I would change the Node type variables to the String Type. You will also need to parse the token[2] so its an int. i.e Integer.parseInt(token[2]);
Related
When attempting to create an iterator from a Stream that was concatenated from two previous streams, I get a NoSuchElementException, as the iterator doesn't recognise that the Stream has elements due to some problems with the Spliterator. The concatenated Stream seems to have two spliterators, despite the previous streams being of the same type. I also get this error when I tried to convert the concatenated stream into an array to try get round the problem.
Stream<Node> nodeStream = Stream.of(firstNode);
while (!goal) {
Iterator<Node> iterator = nodeStream.iterator();
Node head = iterator.next();
Stream<Node> tail = Stream.generate(iterator::next).filter(n -> n != head);
Node[] newNodes = head.expand(end);
if (newNodes.length == 1) {
goal = true;
endNode = newNodes[0];
}
nodeStream = Stream.concat(Arrays.stream(newNodes), tail);
nodeStream = nodeStream.sorted(Comparator.comparing(n -> n.routeCost(end)));
}
The error is as follows:
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Spliterators$1Adapter.next(Spliterators.java:688)
at java.base/java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator$OfRef.tryAdvance(StreamSpliterators.java:1358)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.lambda$initPartialTraversalState$0(StreamSpliterators.java:292)
at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.fillBuffer(StreamSpliterators.java:206)
at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.doAdvance(StreamSpliterators.java:161)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.tryAdvance(StreamSpliterators.java:298)
at java.base/java.util.stream.Streams$ConcatSpliterator.tryAdvance(Streams.java:723)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.lambda$initPartialTraversalState$0(StreamSpliterators.java:292)
at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.fillBuffer(StreamSpliterators.java:206)
at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.doAdvance(StreamSpliterators.java:161)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.tryAdvance(StreamSpliterators.java:298)
at java.base/java.util.Spliterators$1Adapter.hasNext(Spliterators.java:681)
at java.base/java.util.Spliterators$1Adapter.next(Spliterators.java:687)
at inf.ed.ac.uk.Route.generateRoute(Route.java:35)
I am trying to expand the first node (returns 16 new nodes) add them to the stream, sort it, and repeat, this is part of an implementation of the A* algorithm on gps coordinates
Code for Node is
public class Node {
boolean goal = false;
Node parent;
final LngLat coords;
LngLat.Compass direction;
double cost;
private Route route;
public Node[] expand(LngLat end) {
ArrayList<Node> nodes = new ArrayList<>();
for (LngLat.Compass direction: LngLat.Compass.values()) {
Node node = new Node(coords.nextPosition(direction), this, direction);
if (noFlyClear(node)) {
if (!route.contains(node)) {
if (node.coords.closeTo(end)) {
node.goal = true;
return new Node[]{node};
}
nodes.add(node);
route.visited.add(node);
}
}
}
return nodes.toArray(Node[]::new);
}
But that's since I changed to ArrayLists
I'm still unsure what the issue was originally
This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 3 years ago.
I have written a small piece of code to implement a linked list data structure. I have an internal class "Node" that has two fields Node and value. Constructor of Linked list accept int value parameter and assign that value to the Node object and add the Node object to the LinkedList object.
My question is which code of java.util.LinkedList makes the list object to be printed as a list of number but not the address of its object?
As When i print "list1", the output is [3,4].
When I print "list", the output is hashcode of the object address.
I didn't find the toString() in java.util.LinkedList class.
How can I make my code to print the content of LinkedList?
Below is the code:
class LinkedList {
Node first;
Node getNode(){
return new Node();
}
class Node{
Node next;
int value;
}
void add(int value){
Node n=this.getNode();
n.value=value;
n.next=null;
if (first==null){
first=n;
} else{
first.next=n;
}
}
}
public class LinkedListTest{
public static void main(String[] args) {
LinkedList list=new LinkedList();
java.util.LinkedList<Integer> list1=new java.util.LinkedList<>();
list1.add(3);
list1.add(4);
list.add(1);
list.add(2);
System.out.println(list);
System.out.println(list1);
}
}
Your class LinkedList (I suggest you rename it since it might be confused with java.util.LinkedList) needs to override the method Object::toString, which is called within printing out to a console.
I didn't find the toString() in java.util.LinkedList class.
A bit detective job - you have to click through the source codes of LinkedList<E> which extends AbstractSequentialList<E> which extends AbstractList<E> which finally extends AbstractCollection<E> (source code) class where is overridden Object::toString method responsible for the String-alike representation of all the element. There you can get inspired.
How can I make my code to print the content of LinkedList?
This way:
#Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
if (first != null) {
Node temp = first;
String sep = "";
while (temp != null) {
sb.append(sep).append(temp.value);
temp = temp.next;
sep = ", ";
}
}
return sb.append(']').toString();
}
You have to create your own toString method for example
class LinkedList {
//...
#Override
public String toString() {
StringBuilder text = new StringBuilder("[");
String del = "";
if (first != null) {
do {
text.append(del).append(first.value);
first = first.next;
del = ", ";
} while (first != null);
}
text.append(']');
return text.toString();
}
}
If you run your code again, the Outputs
[1, 2]
I have a class called SparseMatrix. It contains an ArrayList of Nodes (also class). I am wondering of how to iterate through the Array and access a value in Node. I have tried the following:
//Assume that the member variables in SparseMatrix and Node are fully defined.
class SparseMatrix {
ArrayList filled_data_ = new ArrayList();
//Constructor, setter (both work)
// The problem is that I seem to not be allowed to use the operator[] on
// this type of array.
int get (int row, int column) {
for (int i = 0; i < filled_data_.size(); i++){
if (row * max_row + column == filled_data[i].getLocation()) {
return filled_data[i].getSize();
}
}
return defualt_value_;
}
}
I will probably switch to static arrays (and remake it every time I add an object). If anyone has a solution, I would very much appreciate you sharing it with me. Also, thank you in advance for helping me.
Feel free to ask questions if you don't understand anything here.
Assuming filled_data_ is a list that contains list of objects of a class named Node.
List<Nodes> filled_data_ = new ArrayList<>();
for (Node data : filled_data_) {
data.getVariable1();
data.getVariable2();
}
More info http://crunchify.com/how-to-iterate-through-java-list-4-way-to-iterate-through-loop/
First of all, you should not use raw types. See this link for more info: What is a raw type and why shouldn't we use it?
The fix is to declare the type of object held by your array list. Change the declaration to:
ArrayList<Node> filled_data_ = new ArrayList<>();
Then you can access each element in the array list using filled_data_.get(i) (as opposed to filled_data_[i], which would work for a regular array).
`filled_data_.get(i)`
The above will return the element at index i. Documentation here: https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#get(int)
If you didn't use generic, then you need to cast the object
//Assume that the member variables in SparseMatrix and Node are fully defined.
class SparseMatrix {
ArrayList filled_data_ = new ArrayList();
//Constructor, setter (both work)
// The problem is that I seem to not be allowed to use the operator[] on
// this type of array.
int get (int row, int column) {
for (int i = 0; i < filled_data_.size(); i++){
Node node = (Node)filled_data.get(i);
if (row * max_row + column == node.getLocation()) {
return node.getSize();
}
}
return defualt_value_;
}
}
If array list contains Nodes which defines getLocation() you could use :
((Nodes)filled_data_.get(i)).getLocation()
You could also define
ArrayList<Nodes> filled_data_ = new ArrayList<Nodes>();
When you create the ArrayList object, you should specify the type of the contained elements with <> brackets. It is also good to keep the reference to the List interface - not ArrayList class. To iterate through such a collection, use foreach loop:
Here is an example of the Node class:
public class Node {
private int value;
public Node(int value) {
this.value = value;
}
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
Here is an example of the Main class:
public class Main {
public static void main(String[] args) {
List<Node> filledData = new ArrayList<Node>();
filledData.add(new Node(1));
filledData.add(new Node(2));
filledData.add(new Node(3));
for (Node n : filledData) {
System.out.println(n.getValue());
}
}
}
I'm trying to create a simple network for Strings modulation.
The idea is the output of the network is the output of the last executed module.
Modules can be arranged in any way and if a module has to connections as an input, the input should be summed (strings concatenation).
To implement it, I'm thinking to represent the network as a graph data structure.
What is blocking me right now is how to determine that module has two connections as the input (so I will be able to sum the two outputs before feeding the result as the input)?
What algorithm to use to traverse the graph? breadth-first?
Any better solution to represent the network?
[pseudo code is highly appreciated]
If you're storing the graph as an adjacency list ("This node points to these nodes"), then you can simply iterate over the adjacency list and swap the A -> B pairs to B -> A, creating an inverse adjacency list ("This node is pointed to by these nodes").
More info in this article.
EDIT:
From your diagram, the adjacency list would be:
A -> [B, C]
B -> [D]
C -> [D]
D -> []
This can be represented as a Map<Node, Collection<Node>>. Write a method that takes a pair and updates the map, call it connect. To build the structure you would call it with connect(A, B), connect(A, C), connect(B, D), connect(C, D).
To invert it, create a new Map to hold inverted structure. Iterate over each key in the map, and then over each value in the list, and call connect on the inverted structure with the arguments reversed.
You could implement this both in a breadth-first, and depth-first. I am gonna post a depth-first algorithm:
public class Node {
private List<Node> parents = new ArrayList<Node>();
private List<Node> children = new ArrayList<Node>();
private Map<Node, String> receivedMessages = new HashMap<Node, String>();
private String id = "";
public Node(String id) {
this.id = id;
}
void processMessage(Node sender, String message) {
if (parents.contains(sender))
receivedMessages.put(sender, message);
// if all the parents sent the message
if (receivedMessages.size() == parents.size()) {
String newMessage = composeNewMessage(receivedMessages);
if (children.size() == 0) // if end node or "leaf"
ouputResult(this, newMessage);
else {
for (Node child : children) {
child.processMessage(this, newMessage);
}
}
}
}
public void addParent(Node parent) {
if (parent != null)
parents.add(parent);
parent.children.add(this);
}
public void addChild(Node child) {
if (child != null)
children.add(child);
child.parents.add(this);
}
private void ouputResult(Node node, String newMessage) {
// TODO: implement
}
private String composeNewMessage(Map<Node, String> receivedMessages2) {
// TODO: implement
return "";
}
public static void main(String[] args) {
Node A = new Node("A");
Node B = new Node("B");
Node C = new Node("C");
Node D = new Node("D");
Node start = new Node("start");
Node end = new Node("end");
A.addParent(start);
B.addParent(A);
C.addParent(A);
D.addParent(B);
D.addParent(C);
end.addParent(D);
A.processMessage(start, "Message");
}
}
class Link {
public Link next;
public String data;
}
public class LinkedList {
public static void main(String[] args) {
String myArray[] = new String[2];
myArray[0] = "John";
myArray[1] = "Cooper";
Link first = null;
Link last = null;
while (myArray.hasNext()) {
String word = myArray.next();
Link e = new Link();
e.data = word;
//... Two cases must be handled differently
if (first == null) {
first = e;
} else {
//... When we already have elements, we need to link to it.
last.next = e;
}
last = e;
}
System.out.println("*** Print words in order of entry");
for (Link e = first; e != null; e = e.next) {
System.out.println(e.data);
}
}
}
LinkedList.java:16: cannot find symbol symbol : method hasNext()
location: class java.lang.String
while (myArray.hasNext()) {
^ LinkedList.java:17: cannot find symbol
symbol : method next() location: class java.lang.String
String word = myArray.next();
^ 2 errors
Few Questions...
Why did this error occur, i am trying to pass my Array of Strings. Still its not taking.
Can't we not declare Array of Strings like in JavaScript way.
String myArray[] = ["assa","asas"];
What does the hasNext() and the next Method do?
Java arrays don't have next and hasNext methods on them. You are probably thinking of iterators, which are typically used with container classes/interfaces such as java.util.List.
Note that you can initialize String arrays thus:
String[] myArray = { "foo", "bar" };
Here is a much more succinct way to iterate through the array
for(String word : myArray) {
//Keep the rest of the code the same(removing the String word = myArray.next(); line
}
That will iterate through the array, assigning the current value to word at each pass.