How to deal with public/private pair in this binary trees? - java

The problem is to add a method to this class that reads from a scanner and constructs a tree with the data from the scannerin preorder fashion.
//the class to add the method readTree to
public class IntTree {
private IntTreeNode overallRoot;
...
}
Here is my solution(I have all of the logic down but having trouble with the public private pair)
public void readTree(Scanner s){
overallRoot = readTree(s);
}
private IntTreeNode readTree(Scanner s){
int type = s.nextInt();
IntTreeNode root = new IntTreeNode(s.nextInt());
if(type % 2 == 1){
root.left = readTree(s);
}
if(type==2 || type==3){
root.right= readTree(s);
}
return root;
}
Our style(in general too) is to use a public/private method approach to binary trees. That is take advantage of x=change(x). The return type of the public method should be void(given directions). The return type is IntTreeNode for the private helper because of the returning change(x) part. My question is how would you accompany my set directions of public/private pair, that is write the method signature of the private helper. For my current code, the compiler gives me a duplicate method(i expected that bc the two had the same method signature. I thought about introducing some arbitrary parameter and setting it to null but thought that was bad style. Unlike other problems, you don't need to pass in the int tree node as a parameter bc you don't work with existing data, you're constructing it all from scratch

I think the most straightforward approach would be to name the private method something slightly different, maybe
private IntTreeNode readTreeRecursive(Scanner s)
or
private IntTreeNode readTreeInternal(Scanner s)
is there a reason you can't do something like this?

Related

Creating a method that can only input a certain types of strings that are predetermined

I have the following type of Strings
"Move 1 place forwards";
"Move 1 place backwards;
Can I create a type called 2dMotion, where a method can only take in these two strings as arguments in Java.
public 2dMotion message(){ return "Move 1 place forwards"; }
For example if a method was classed that had 2dMotion as an input then it wouldn't be able to input anything but those 2 sentences
You can declare them as constants in a class, and provide direct access to them by making them public:
public MyClass {
public static final MOTION_FORWARD = "Move 1 place forward";
public static final MOTION_BACKWARDS = "Move 1 place backwards";
// Rest of the class omitted
}
Or, a better solution is to use an Enum.
public enum MOTION {
FORWARD("Move 1 place forward"),BACKWARDS("Move 1 place backwards");
private final String val;
private MOTION(String val) {
this.val = val;
}
public String getVal() {
return val;
}
}
To use the constant, simply use MyClass.MOTION_FORWARD. To use the enum, you could do MOTION.FORWARD.getVal();
Lastly, as good practice, you should override toString() method:
#Override
public String toString() {
return val;
}
Even though this method does the same as getVal(), it is consider good practice to do so. If you would like to remove one of those methods, it should be the getVal() method. Also, even though the enum solution involves more code, it is also considered to be a better solution. Also, when you override toString(), it allows to return the value of the enum without invoking toString() or getVal() directly. For example, System.out.println(MOTION.BACKWARDS); prints out "Move 1 place backwards".

What's the difference between these two linked list constructor?

class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
static class LinkedList {
int value;
LinkedList next = null;
public LinkedList(int value) {
this.value = value;
}
}
I'm new to programming and now practicing algorithms. And I see these two different versions of the constructor in various websites. Can someone give me some examples or use-cases of how to use these constructors?
The specific versions you present boil down to the same thing. Both have a field storing the current node's value (val and value). Likewise, both have a reference to the next node (next) that is null at initialization time.
There's isn't any functional difference between those two versions, apart from the static vs. non-static class and public vs package-private constructor.
Both give the same result, but it depends on each programmer to use them, a good practice that many programmers choose is to leave the variables initially empty and give their values in the constructors or methods. Hugs!

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).

Deciding to use Comparable or Comparator

My program implements a Product class whose objects contain the following instance variables: name, priority, price, and amount.
I have a LinkedList of Product objects that I need to sort before doing any other operations on the LinkedList.
I want to sort the list first by priority (from lowest to highest). If priority is the same, then look at the price (lowest to highest), then the name (alphabetical order).
I have done a lot of reading about Collections.sort, Comparable, and Comparator. I believe I need to use the Comparable interface and implement a compareTo method. My thinking is that because both priority, price, and name have a "natural" ordering it makes more sense to use Comparable.
public class Product extends ProductBase implements PrintInterface, Comparable<Product>{
private String name;
private int priority;
private int cents;
private int quantity;
// setters and getters
/**
* Compare current Product object with compareToThis
* return 0 if priority, price and name are the same for both
* return -1 if current Product is less than compareToThis
* return 1 if current Product is greater than compareToThis
*/
#override
public int compareTo(Product compareToThis)
}
Then when I want to sort my LinkedList I just call Collections.sort(LinkedList). Before I start writing the code, can you tell me if I am I missing or forgetting anything?
*************UPDATE*******************************
I just created a separate class called ProductComparator with a compare method.
This is part of the LinkedList class..
import java.util.Collections;
public class LinkedList {
private ListNode head;
public LinkedList() {
head = null;
}
// this method will sort the LinkedList using a ProductComparator
public void sortList() {
ListNode position = head;
if (position != null) {
Collections.sort(this, new ProductComparator());
}
}
// ListNode inner class
private class ListNode {
private Product item;
private ListNode link;
// constructor
public ListNode(Product newItem, ListNode newLink) {
item= newItem;
link = newLink;
}
}
}
I am getting the following error from the IDE when I compile.
The method sort(List, Comparator) in the type Collections is not applicable for the arguments (LinkedList, ProductComparator).
Does anyone know why I am getting this error and can point me in the right direction to resolve it?
If there is a "natural" ordering, use Comparable. Rule of thumb for figuring out if the ordering is "natural" is, whether the order of the objects will always be that.
Having said that, the decision whether to use Comparable or Camparator is not the kind of decision you need to think too much about. Most IDEs have refactoring tools which makes the conversion between a Comparable and a Comparator very easy. So if you choose to walk the wrong path now, changing that will not require too much effort.
The order you define here on your Product is very specific and
will probably change in future versions of your program
might be enriched with contextual parameterization
won't cover new features
So it can hardly been said "natural".
I'd suggest to define a constant, for example
public static Comparator<Product> STANDARD_COMPARATOR = new Comparator<Product>() {
public int compare(Product p1, Product p1) {
return ...
}
};
then you'll be able to easily sort anywhere with
Collections.sort(myProductList, Product.STANDARD_COMPARATOR);
Your code will evolve in a better manner as you'll add other comparators.
Just like you should generally prefer composition over inheritance, you should try to avoid defining the behavior of your objects in immutable manner.
If your order was based only on numbers, Comparable would be fine.
However, since your order (sometimes) involves lexical order of text,
a Comparator class is better, since use of Comparable would mean using
String.compareTo which would prevent you from having internationalization.
A separate class which implements Comparator can make use of a
localized Collator for comparing Strings. For instance:
public class ProductComparator
implements Comparator<Product> {
private final Collator collator;
public ProductComparator() {
this(Locale.getDefault());
}
public ProductComparator(Locale locale) {
this.collator = Collator.getInstance(locale);
}
public int compare(Product product1,
Product product2) {
int c = product1.getPriority() - product2.getPriority();
if (c == 0) {
c = product1.getPrice() - product2.getPrice();
}
if (c == 0) {
c = collator.compare(product1.getName(), product2.getName());
}
return c;
}
}
Regardless of whether you go with Comparable or Comparator, it is wise
to make sure Product has an equals method which checks the same
attributes as the comparison code.

How to initialize Key Class in HashMap in Java

I have a question related to Key Type initialization in HashMap. For example, I have defined the below Node class with over-ridden equals() and hashCode() as follows:
public class Node implements Comparable<Node> {
private int Id;
public Node(int i) {
...
}
void setId(int i) {
Id = i;
}
int getId() {
return Id;
}
#Override
public boolean equals(Object o) {
if (o == null) {
throw new NullPointerException();
}
if (o instanceof Node && this != o) {
if (((Node) o).getId() == this.getId())
return true;
}
return false;
}
public int hashCode() {
return Id;
}
}
Now I am building a HashMap with key as type Node as follows:
public class AdjList {
public HashMap<Node,Double> adj;
public AdjList() {
adj = new HashMap<Node,Double>(maxSize);
}
...
}
As you can possibly figure out, I am trying to generate a graph adjacency list with the node class as HashMap.
Now, my question is when I call AdjList() constructor where I create a new HashMap with some maxSize, will it initialize the Node() class as key type? Or I need to separately initialize Node() clas for the key? If I need to initialize Node() in AdjList constructor, then how it can be possible?
Any suggestion will be valuable and useful suggestions will be rewarded.
Thanks,
Somnath
when I call AdjList() constructor where I create a new HashMap with some maxSize, will it initialize the Node() class as key type?
No! You are instantiate the Map with initialCapacity which is the loadFactor value not maxSize (See the documentation).
You may define a method in AddList that adds an entry.
public void add(int i,Double d)
{
adj.put(new Node(i),d);
}
Second, you've implemented Comparable so you must have to define the compareTo method.
There are a number of things that confuse me about your question (even after reading about adjacency lists which I had not heard of before). Firstly why is overriding equals and hash map important? Secondly how does this code form an adjacency list (reading http://en.wikipedia.org/wiki/Adjacency_list) I could not see the relationship between what you have and an adjacency list. I'm also not sure what you are asking when talking about initialising the Node class. It sounds like yoga re confused about some things, I'm just not sure what.
Finally, based on what I read about adjacency lists, I would simply use the following code:
Map<int, List<int>> adjList = new HashMap<int, List<int>>();
Then I can store node 1 with a adjacency list of nodes 2 and 3 as:
adjList.put(1, Arrays.aslist(2,3));
and retrieve then with:
adjList.get(1);
etc, etc. No need for any custom classes at all.

Categories