Using an Interface in Java - java

Well I have a fairly simple question I just can't seem to find my way around...
For a class, I have to implement an interface for a binary tree that has a method like:
public List<Node<E>> listAll();
we are required to have a class called MyNode.java, which is what I use to make my tree with. So to list all children I thought I would do this:
public List<Node<E>> listAll(){
List<Node<E>> childList = new ArrayList<>();
MyNode<E> thisNode = this.l;
while(thisNode!= null){
childList.add(thisNode);
thisNode = thisNode.l;
}
return childList;
}
and to do something like set a child
public void setChild(Node<E> child){
E elem = child.getElement();
MyNode<E> newNode = new MyNode(elem);
this.l = newNode;
}
So my question is: am I going about this correctly? If I try to create a Node, I can't because my nodes are called MyNodes but when I try to create a list of MyNodes and return them it gives me an error because I am not following the interface.. When I try to make the method accept MyNode instead of Node it says I am not following the interface. A little more clarification below..
I currently am using the implements declaration to implement the Node.java interface.. When I am writing the method that is specified by my interface as:
public void setChild(Node<E> child);
then I am currently fleshing out the method like so:
public void setChild(Node<E> child) {
E elem = child.getElement();
MyNode<E> newNode = new MyNode<E>(elem);
MyNode<E> transNode = this.l;
if(transNode!=null){
while(transNode.r!=null){
transNode = transNode.r;
}
transNode = newNode;
}
else transNode = newNode;
}
you can see how I am getting the element from input child and creating a new MyNode out of it to put as the new child instead of just injecting Node into my tree.. Is this wrong? I can't seem to get another way to work...

Interfaces are good for making code generic. If you wanted to have multiple implementations of a Node class that each would have the same methods then making an interface would be a good idea.
Alternatively, if you want to enforce an API for someone else to use, and interface is the right way to do that. You can make methods that accept any object that implements that interface.
If you're just creating one Node class for a simple binary tree implementation it might not make sense. Your binary tree might want to implement a Collection interface to make it available as a generic structure.
If you want to contractualize yourself to an API before beginning, an interface could further be a good way to do that.

In general you don't want to create an interface unless you want an abstraction where you actually will write different implementations of that abstraction. In your case, class Node<T> will suffice for your needs.

It is generally considered good form to use an interface for the API.
Briefly, doing so:
allowing the caller to provide whatever implementation they like
makes testing easier, especially when using mocks
chisels the least amount of the API in stone
See Liskov substitution principle

Related

how can you pass an object to a function as a parameter, then have the function to assign a new object of a subtype to its parameter?

I'm trying to build up a compiler using the recursive descent parsing method and visitor pattern for semantic checking with Java. The thing that confuses me is to use visitor patterns, we have to create different subtypes. However, Java doesn't pass by reference. Which caused me that I cannot end up with the right subtype for each semantic records. Here is what I'm trying to implement
Node node = new ExprNode();
changeNodeType(node);
public void changeNodeType(Node node) {
node = new AddOpNode();
}
then eventually my Node type will end up with AddOpNode(). Is there any way that I could eventually implement this in Java?
You could just return the new node type and assign it outside of the function.
Node node = new ExprNode();
node = changeNodeType();
public Node changeNodeType() {
return new AddOpNode();
}

How to use Comparator<T> as an argument in a generic SortedDoublyLinkedList

I am currently working on an assignment for class where I am tasked with creating an empty List that has a Comparator as an argument then creating an add method for that sortedDoublyLinkedList where I am passed an argument and I have to iterate through the list to find where the new node fits. I'm not very familiar with Comparator so I'm a bit clueless as to how to add elements to my DoublyLinkedList because I cannot access the Comparator the way I though I was supposed to. Here is what I have now. Here is what I currently have.
public class SortedDoubleLinkedList<T> extends BasicDoubleLinkedList<T> {
Node<T> head=null;
Node<T> tail=null;
SortedDoubleLinkedList<T> sDLL;
public SortedDoubleLinkedList(Comparator<T> comparator2){
sDLL=new SortedDoubleLinkedList<T>(comparator2);
}
public SortedDoubleLinkedList<T> add(T data){
Node<T> newNode=new Node<T>(data);
//I have to iterate through the list and find where the new element data fits
if(head!=null&&tail!=null) {
Node<T> cursor=head;
while(cursor!=null) {
//the following code doesn't work
if(sDLL.comparator2.compare(data, cursor.getData())==0) {
}
}
}
else {
head=newNode;
tail=newNode;
}
return this; //return the SortedDoubleLinkedList<T>
}
Comparator is an interface. You need to implement a class that will provide that interface.
class Whatever implements Comparator<TYPE> {
int compare(TYPE a, TYPE b) {
... code to decide whether a is less than,
equal to, or greater than b ...
}
}
Where I wrote TYPE, you need an actual type. Just supplying the type variable T is not going to get you to runnable code, which I assume is your goal. Ultimately you've got to say what type will go in your list. So I'd be expecting something like (in your code above)
public class SortedDoubleLinkedList extends BasicDoubleLinkedList<String> {
where you're storing Strings in your list. And then TYPE in my code is also String.
ALTERNATIVELY
You can leave your SortedDoubleLinkedList generic (in terms of T) but ultimately you want to get concrete about it, maybe
SortedDoubleLinkedList<String> = new SortedDoubleLinkedList(new Whatever());
but the Comparator is still going to need to be a Comparator<String> (or whatever type you choose).

Implement Array using linkedlist

This was asked in an interview.
Can you implement/create an object in java which is similar to Array class in java.
basically we should be able to iterate over the object like we do with arrays and getValue() or putValue() methods should be able to directly work on index of the object created.
ex: below operation should be performed with created object.
int ar[] = new int[5];
for(int i=0; i<5; i++){
ar[i]=i;
}
Hint given was to use linkedlist data structure.
in simple words its the similar like ArrayList class implementation.
can anyone give me an idea how can we do this?
He was asking about nested objects. please read about decorator pattern. please see the below example.
public interface NodeInterface{
// your methods
}
public class Node implements NodeInterface{
private NodeInterface node = null;
// your methods
}
There every node contains nested object of same type. last object that have no object points to a null. you can traverse untill you find a null.
I've asked a similar question before which has been answered, and it has to do with the concept of nodes and linked list. My question can be found by following this link
Problems understanding concept of nodes and linked list
I accepted the answer because it helped me visualize what the linked list would look like and what my Node class would look like.
When you do make the node object, you can then make custom classes to change to value of what that node is storing, as well as retrieving and displaying the data stored in the node.
The node class would look something like this
public class Node{
private int val;
private Node node;
public Node(int val){
this.val=val;
}
public Node(Node node, int val){
this.node = node;
this.val = val;
}
public Node getNext(){
return node;
}
public int getVal(){
return val;
}
}
Obviously you can modify the code to store anything you want, but this is probably what the interviewers were looking for.
Using LinkedList it should looks like:
LinkedList<Integer> linkedList = new LinkedList<>();
for(int i=0; i<5; i++){
linkedList.add(i);
}
However, I'm giving you the link for beginners in which you can lear everything about the java util package. Good luck.

How to implement Graph search (DFS) with Object Oriented design [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I'm not so sure about what's the best approach to model this problem in the object oriented world.
Suppose I have to represent a graph and its nodes in Java and suppose I want to traverse the graph using a depth first search (DFS).
What is the best approach in Software engineering among these two:
Create a class Node, a class Graph and a class GraphsFunctions where the GraphsFunctions class contains the DFS method which takes the Graph and a Node as parameters. Something like this: public void DFS(Graph g, Node n) and the call new GraphsFunctions().DFS(new Graph(), new Node())
Create a class Node and a class Graph where the class Graph contains the method DFS which only takes a Node as a parameter. Something like this: public void DFS(Node n) and the call new Graph().DFS(new Node())
I would rather use the first of the two options but I can't say why it's the best for me. Can you tell me what makes the best choice, actually the best?
This really depends on mostly two things:
How much encapsulation you want in your project. More encapsulation is usually better, but it can come at the price of over engineering the problem, which can cause a lot more work which you want to avoid for small projects which wont grow over time.
Your own personal style. Each developer will develop his or her own style over time which will be clearly distinguishable from other developers. The most important thing is consistency throughout a project
Assuming you want (only) good encapsulation I would personally do it like the following..
Create an interface GraphSearch and define your search(Graph g, Node n) method in there. Now have a class called DFSearch and possibliy BFSearch.
If - at some point - a method wants to perform searches on a Graph you can specify the search algorithm which should be used.
If you want great encapsulation, I would recommend using the iterator pattern as DFS and BFS are basically just iteration orders.
Start by creating an Interface GraphIterator instead. It simply extends Iterator<Node> which means it can iterate over Nodes in some order.
public interface GraphIterator extends Iterator<Node> {
}
Create as many implementations of this algorithm as you like. An empty construct for DFS looks like this:
public class DFSIterator implements GraphIterator {
private Graph g;
public DFSIterator(Graph g) {
this.g = g;
}
#Override
public boolean hasNext() {
// todo: implement
return false;
}
#Override
public Node next() {
// todo: implement
return null;
}
}
Next you can still create your Interface GraphSearch..
public interface GraphSearch {
Node search(Graph g, Node n);
}
And one simple implementation would be IterationSearch which can only perform searches with a given Iterator.
public class IterationSearch {
public Node search(Graph g, Node n, GraphIterator iter){
Node current = null;
while (iter.hasNext()){
current = iter.next();
if (current.equals(n)){
return n;
}
}
return null;
}
}
It just iterates over the Iterator and compares each element to the searched node. Next create your class DFSearch which is the first actual GraphSearch...
public class DFSearch extends IterationSearch implements GraphSearch{
#Override
public Node search(Graph g, Node n) {
return search(g, n, new DFSIterator(g));
}
}
Now your Graph can extend Itarable<Node> and return one of your iterators as the default iterator. This way you could nicely iterate over your Graph.
public class Graph implements Iterable<Node> {
#Override
public Iterator<Node> iterator() {
return new DFSIterator(this);
}
}
and use it like the following:
Graph g = createGraph();
for (Node n : g) {
// do things...
}
The great thing about this solution is that you can make the Iterators inner classes of your Graph, which allows them to access private members. This often improves performance significantly as you don't have to treat the Graph as a black box.
Best in terms of fast-to-code, easy-to-modify, or some other criterion? Unless you come up with a very precise definition of "what is good", do not expect to find "best".
My first answer would be to use a graph library for Java. Most come with DFS already implemented:
Already implemented and debugged.
Good documentation.
No company will generally want me to reinvent the wheel.
However, since your question is probably part of a do-it-yourself course, I would instead recommend:
Node class, which can provide access to neighbors, and has equals and hashcode methods.
Graphs class, which can build graphs and display them. Includes a Dfs(Graph g, Node start, DfsVisitor visitor) method. This would be a utility class with all-static methods, in the same vein as JDK's Collections or Files.
Graph class, with a list of nodes (and possibly other things, such as the possibility of returning an iterator to a list of edges).
DfsVisitor, an interface for visitors:
Main class, which builds a graph and calls your DFS on the graph with the useful payload in the visitor.
Because DFS by itself is useless - it is just a node-visiting strategy. Its value is in what it does before and after it visits a node. Unless you allow this to be customized, placing a DFS algorithm into GraphsFunctions or Graphs makes no big difference: it is not likely to be reused outside of whatever payload you have built into it.
public interface DfsVisitor() {
void started(Graph g, Node node); // when first encountered
void finished(Graph g, Node node); // when all children processed
}

Node losing the reference to another object when passed through function

I'm working with double-ended queues for an assignment, and we're running into an issue where the object reference is disappearing from a node after being passed through an extremely simple method.
Some important definitions:
class Node {
String s;
Node prev;
Node next;
...
}
class Sentinel extends Node {
Node prev;
Node next;
//Constructor uses that of Node
}
class Deque {
Sentinel start;
...
}
One method we are writing removes a Node from a deque, based on the given string.
In deque:
public void removeSorted(String toRemove) {
// System.out.println(this.start);
// System.out.println(this.start.next);
this.start.next.removeSorted(toRemove);
}
The commented out println's show the correct Sentinel and Node.
Then, in Node:
public void removeSorted(String toRemove) {
if (this.s.equals(toRemove)) {
// System.out.println(this.prev);
// System.out.println(this.prev.next);
this.prev.next = this.next;
this.next.prev = this.prev;
} else if (this.s.compareTo(toRemove) > 0) {
throw new RuntimeException("String does not exist in these nodes!");
} else {
this.next.removeSorted(toRemove);
}
}
The println for this.prev outputs the Sentinel on the first recursion, as expected. However, this.prev.next outputs null instead of the Node.
This function only fails when trying to remove the first Node, directly after the Sentinel. If you try to remove any other Node, it works correctly, and trying to call this.prev.next results in a non-null answer.
Why does the reference disappear when passing to the function (immediately after), since we've shown that the reference is there directly before calling the function?
Either your question code is wrong, or you have same fields in both Node and in Sentinel. This means, that these two are different:
start.next is next field of Sentinel class, which hides field with same name from Node class.
start.next.prev.next is also a field of start, but now it is the field of Node class, because you access it through Node reference.
Remove prev and next from Sentinel. Actually remove the whole Sentinel, it looks like you use to to "remove" the String s, which is impossible, you can't "remove" super class fields. Or if you need/want sentinel, see below for alternative design.
Also, this demonstrates why you should use getters and setters instead of accessing fields directly... Your IDE probably has nice refactoring tool to add getters etc (right click on field, see "Refactor" submenu), use it! And if your IDE does not have that, switch to one which does (I prefer NetBeans, but Eclipse and IntelliJ are worthy too), writing Java without such an IDE is an exercise in masochism...
Also, in Java avoid that kind of inheritance. You should probably have this kind of overall design:
interface NodeInterface {...}
public class Node implements NodeInterface {...}
public class Sentinel implements NodeInterface {...}
Then in the NodeInterface, define getters and setters, which should take as parameters as well as return NodeInterface type. Sentinel class would not support all interface methods of course, so those methods can either return null;/do nothing, or throw new IllegalStateException("Sentinel does not support Xxxx."); depending on method and if calling that method for sentinel is bug in calling code or not (better start with throwing exception).
If this is school work and you have not gone over interfaces yet, then replace interface NodeInterface with class NodeBase (preferably abstract), but in "real world" this would be bad code, because Java does not support multiple inheritance.

Categories