So I am trying to add a few strings to a Doubly Linked list but I keep getting the error that String cannot be converted to PubliclyCloneable (an interface that extends Cloneable, use for the purposes of creating a clone() and copy constructor, a la my textbook's explanation). Here is what my demo code looks like:
public static void main(String[] args)
{
DoublyLinkedList list1 = new DoublyLinkedList();
DoublyLinkedList.DoublyLinkedIterator i = list1.iterator();
String pittsburgh1 = new String("Penguins");
String pittsburgh2 = new String("Pirates");
String pittsburgh3 = new String("Steelers");
list1.addToStart(pittsburgh1);
list1.addToStart(pittsburgh2);
list1.addToStart(pittsburgh3);
System.out.println("List contains:");
i.restart();
while (i.hasNext())
System.out.println(i.next());
System.out.println("");
Here is the beginning part of the class DoublyLinkedList:
public class DoublyLinkedList<T extends PubliclyCloneable> implements PubliclyCloneable
{
private class TwoWayNode<T>
{
private T data;
private TwoWayNode<T> next;
private TwoWayNode<T> prev;
public TwoWayNode()
{
data = null;
next = null;
prev = null;
}
public TwoWayNode(T newData, TwoWayNode<T> prevNode, TwoWayNode<T> nextNode)
{
data = newData;
next = nextNode;
prev = prevNode;
}
}
Here is the method that is causing the compiler error:
public void addToStart(T itemData)
{
TwoWayNode<T> newHead = new TwoWayNode(itemData, null, head);
if (head != null)
{
head.prev = newHead;
}
head = newHead;
}
And here is the interface that I am using:
public interface PubliclyCloneable extends Cloneable
{
public Object clone();
}
So there is probably something that I am overlooking here, but is what I am trying to accomplish even possible? Is there some sort of typecast or type assignment I can do to add those three strings to my List?
Your addToStart method accepts an argument of type T, where T is defined by the class as T extends PubliclyCloneable.
Since java.lang.String does not implement PubliclyCloneable, it cannot be an argument type for your DoublyLinkedList. If you want a main function to test your class, I'd implement a simple-stupid PubliclyClonableString class::
public class PubliclyClonableString implements PubliclyClonable {
private String s;
public PubliclyClonableString (String s) {
this.s = s;
}
#Override
public String clone() {
return s; // OK, since Strings are immutable
}
// getter, setter, etc.
}
You're trying to add Strings to a list that you have declared will hold PubliclyCloneable. Either put PubliclyCloneable objects in it or declare that it will hold Strings.
Since DoublyLinkedList requires a class which extends PubliclyCloneable, you'll have to make your custom string class:
public class CloneableString implements PubliclyCloneable {
private String str;
public CloneableString(String str) {
this.str = str;
}
public String getString() {
return str;
}
#Override
public Object clone();
return new CloneableString(str);
}
}
Related
I am trying to create Expression Tree using the Postfix Expression.
This needs a Stack which could hold Tree Objects.
I created a generic Stack class which could except <TreeTemp> as type argument.
On trying to initialize the stack with following statement, its giving "Cannot infer type arguments for TreeStack<>" error.
private TreeStack<TreeTemp> stack1 = new TreeStack<>(new TreeTemp());
Stack Class:
public class TreeStack<T> {
private T [] stackElem;
private final int MAXSTACKSIZE;
private int top;
public TreeStack(Class<T> t) {
top = -1;
MAXSTACKSIZE = 20;
final T[] stackElem = (T[]) Array.newInstance(t, MAXSTACKSIZE);
this.stackElem = stackElem;
}
public void push(T elem) throws Exception{
if(isFull()) {
stackElem[++top] = elem;
}
else
throw new Exception("Stack is already Full");
}
public T pop() throws Exception {
if(isEmpty()) {
return stackElem[top--];
}
else
throw new Exception("Stack is Empty");
}
public boolean isEmpty() {return top == -1;}
public boolean isFull() {return top==MAXSTACKSIZE-1;}
}
Postfix.class(Class having method for creating tree)
public class PostFix {
private String expression = new String("A*B+C");
private char [] expElem = expression.toCharArray();
/*Error on below Statement*/
private TreeStack<TreeTemp> stack1 = new TreeStack<>(new TreeTemp());
public TreeTemp makeTree() throws Throwable {
try {
for(int i=0;i<expElem.length;i++) {
ExpNode eNode = new ExpNode();
eNode.setiData(expElem[i]);
TreeTemp t = new TreeTemp();
t.setRoot(eNode);
if(!Character.isLetter(expElem[i])) {
t.setLeftTree(stack1.pop());
t.setRightTree(stack1.pop());
}
stack1.push(t);
}
return stack1.pop();
}catch (Exception e) {
throw new Exception("Stack Error while creating a Tree", e);
}
}
public static void main(String[] args) throws Throwable {
PostFix pf = new PostFix();
TreeTemp t = pf.makeTree();
}
Tree Class(Type which i want to add into Stack):
public class TreeTemp {
private ExpNode root;
private TreeTemp leftTree;
private TreeTemp rightTree;
/*public TreeTemp(ExpNode expNode) {
root = expNode;
}*/
public TreeTemp getLeftTree() {
return leftTree;
}
public void setLeftTree(TreeTemp leftTree) {
this.leftTree = leftTree;
}
public TreeTemp getRightTree() {
return rightTree;
}
public void setRightTree(TreeTemp rightTree) {
this.rightTree = rightTree;
}
public ExpNode getRoot() {
return root;
}
public void setRoot(ExpNode node) {
this.root = node;
}
}
Can someone pls give some pointers.
Your TreeStack has only one constructor. Here it is:
public TreeStack(Class<T> t) {
Thus, to invoke it, you need to pass the class object that represents the class associated with the T type. So, the class itself, not 'some particular instance of T'. When you call it on your error line:
private TreeStack<TreeTemp> stack1 = new TreeStack<>(new TreeTemp());
You are passing an instance of TreeTemp. Not the concept 'TreeTemp, the class'. Try new TreeStack<>(TreeTemp.class);
Note that as a general rule, passing a Class<T> is a code smell; you're trying to make generics something that it isn't (you're trying to runtime reify). This is objectively bad: It means you can't make a TreeStack<List<String>>, for example, because you're restricted to the overlap where both generics as well as j.l.Class instances can represent the thing, and that's just simple, non-genericsed, non-primitive classes.
final T[] stackElem = (T[]) Array.newInstance(t, MAXSTACKSIZE);
Looks like the only reason you want that class is to make sure your array is properly typed.
This is not neccessary. Just make a new Object[] array, and cast to T anytime you need to return a T. Now your TreeStack constructor needs no arguments at all.
Check the source of java.util.ArrayList, which agrees with this assessment; it is backed by an Object array, not a T[].
The TreeStack constructor accepts a Class<T>, not a T, so you should do:
new TreeStack<>(TreeTemp.class);
Since this is an exercise to create expression trees, you don't really need to implement stacks from scratch. You should just use the ArrayDeque class through the Deque interface in the Java Collections API.
private Deque<TreeTemp> stack1 = new ArrayDeque<>();
Deque has all the methods your TreeStack has, and many more.
for uni we are supposed to implement an iterator for a String linked list by ourselves. But the infos how to do that was pretty small. So we tried it by ourselves and googled a lot but all the explanations we found dont include the whole code and I dont get how to implement the iterator correct. I think everything works fine as long as we use the for each loop to use the iterator but as soon as we are trying to use the "while (iterator.hasnext) { next }" thing it stays in the first element of the linked list. I think I know this problem is based on that we are always instantiating a new iterator but I dont get how to implement it else. Hopefully someone can help, I really don't know what to do, I tried everything..
import java.util.Iterator;
import java.util.NoSuchElementException;
public class LinkedList implements Iterable<String> {
// ---------- Attributes ----------
private int size = 0;
private Node head = null;
// private Iterator<String> linkedListIterator = this.iterator(); // ??
static class Node {
// ---------- Attributes ----------
private String object;
private Node next;
// ---------- Constructors ----------
public Node(String object, Node node) {
this.object = object;
this.next = node;
}
public Node() {
this(null, null);
}
// ---------- Getter, Setter ----------
public String getElement() {
return this.object;
}
public void setElement(String object) {
this.object = object;
}
public Node getNext() {
return this.next;
}
public void setNext(Node node) {
this.next = node;
}
}
class LinkedListIterator implements Iterator<String> {
// ---------- Attributes ----------
private Node currentNode = null;
private int counter = 0;
// ---------- Constructor ----------
public LinkedListIterator(LinkedList linkedList) {
this.currentNode = linkedList.head;
}
// ---------- Getter, Setter, Methods ----------
public boolean hasNext() {
return this.currentNode != null;
}
public String next() {
if (!this.hasNext()) {
System.out.println("Fehler: ");
throw new NoSuchElementException();
}
String object = this.currentNode.getElement(); // ?
this.currentNode = this.currentNode.getNext();
this.counter++;
return object;
}
public int getCounter() {
return this.counter;
}
}
// ---------- Getter, Setter, Methods ----------
public Node getHead() {
return this.head;
}
public void addFirst(String object) {
// new node as head
Node newNode = new Node(object, this.head);
this.head = newNode;
this.size++;
}
public String getFirst() { //throws ListEmptyException {
if (isEmpty()) {
// throw new ListEmptyException();
}
return this.head.getElement();
}
public String removeFirst() { //throws ListEmptyException {
if (isEmpty()) {
// throw new ListEmptyException();
}
String object = this.head.getElement();
this.head = this.head.getNext();
return object;
}
public boolean isEmpty() {
return this.head == null;
}
public int getSize() {
return this.size;
}
#Override
public Iterator<String> iterator() {
System.out.println("helo");
return new LinkedListIterator(this);
}
public String toString() {
String output = "";
// this is working:
// for (String element: this) {
// output += element + "\n";
// }
while (this.iterator().hasNext()) {
System.out.println(this.iterator().hasNext());
output += this.iterator().next() + "\n";
}
return output;
}
public static void main(String[] args) {
LinkedList ll = new LinkedList();
ll.addFirst("a");
ll.addFirst("b");
ll.addFirst("c");
ll.addFirst("d");
ll.addFirst("e");
System.out.println(ll.toString());
}
}
Problem solved by this
But new question: Why is this working
public String toString() {
String output = "";
Iterator<String> iterator = this.iterator();
while (iterator.hasNext()) {
output += it.next() + "\n";
}
return output;
}
But this not
public class LinkedList implements Iterable<String> {
private Iterator<String> linkedListIterator = this.iterator();
public String toString() {
String output = "";
while (this.linkedListIterator.hasNext()) {
output += this.linkedListIterator.next() + "\n";
}
return output;
}
}
Your implementation of LinkedListIterator is correct, the problem is in the toString() method.
You are calling this.iterator() 3 times, so each time you return a new instance of LinkedListIterator.
Instead you have to call this.interator() only once and use the instance you get.
Like this:
Iterator<String> it=this.iterator();
while (it.hasNext()) {
System.out.println(it.hasNext());
output += it.next() + "\n";
}
Regarding the new question.
If you instantiate the private Iterator<String> linkedListIterator attribute in the body of the class, (Something that should never be done), every time you refer to it you will make a call to the public Iterator<String> iterator() method and you will get a new instance of LinkedListIterator.
You are making the same mistake as in the beginning.
This is an example of why attributes should be instantiated only within a method declaration.
Remember that an iterator can only move forward, if you want to restart it you must create a new instance. That's what you do by calling this.iterator().
I recommend you to use some debugging tools so you can see the instructions that are executed
Also, there is a design pattern that deals iterators.
https://en.wikipedia.org/wiki/Iterator_pattern
I have created my own linked list implementation that stores a first name and a last name. Now I am trying to sort the list of names alphabetically by the last name, which I am having trouble doing. I have read about possibly using collections.sort but I am not sure how I can modify my class so I can use collections.sort or if that is even a good way to go about it or not. Below is what I have done so far. If anyone could help me with this it would be greatly appreciated. What I want to accomplish is that when I print it will print Joe Rogers, Bill Thomas, Greg West, which would mean it was sorted by last name.
Edit: Thanks everyone for your quick responses, I really appreciate it.
class Test {
public static void main(String[] args)
{
LinkedList l = new LinkedList();
l.insert("Greg", "West");
l.insert("Joe", "Rogers");
l.insert("Bill", "Thomas");
l.print();
Collections.sort(l) // I am unable to get this to work
}
public static class myLink {
public myLink next;
public String first;
public String last;
public myLink(String first, String last)
{
this.first = first;
this.last = last;
}
public void print()
{
System.out.printf("%s %s\n",first,last);
}
}
public static class LinkedList {
private myLink linkedList;
public LinkedList()
{
linkedList = null;
}
public void insert(String first, String last)
{
myLink li = new myLink(first, last);
li.next = linkedList;
linkedList = li;
}
public void print()
{
myLink c = linkedList;
while(c != null)
{
c.print();
c = c.next;
}
}
}
}
LinkedList will work for you. You only need your Person class, and a customised Comparator as in below example.
public class Person {
String first;
String last;
public Person(String f, String l) {
this.first = f;
this.last = l;
}
}
public class LinkExample {
public static void main(String[] args) {
LinkedList<Person> pList = new LinkedList<Person>();
pList.add(new Person("AFirst","ZLast"));
pList.add(new Person("BFirst","BLast"));
Collections.sort(pList, new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return p1.last.compareTo(p2.last);
}
});
System.out.println(pList.pollFirst().last);
System.out.println(pList.pollFirst().last);
}
}
I have tried using Java's linked list, but the add method only lets you use a single string
No, you can add your class as well. Simply implements Comparable interface add put your logic in overridden compareTo() method.
Use Collections.sort() to sort the list.
sample code:
public static void main(String[] args) {
LinkedList l = new LinkedList();
l.add(new MyLink("Greg", "West"));
l.add(new MyLink("Joe", "Rogers"));
l.add(new MyLink("Bill", "Thomas"));
Collections.sort(l);
for(MyLink link:l){
link.print();
}
}
public static class MyLink implements Comparable<MyLink>{
public MyLink next;
public String first;
public String last;
public MyLink(String first, String last) {
this.first = first;
this.last = last;
}
public void print() {
System.out.printf("%s %s\n", first, last);
}
#Override
public int compareTo(MyLink o) {
int result = this.last.compareTo(o.last);
if(result==0){
result = this.first.compareTo(o.first);
}
return result;
}
}
output:
Joe Rogers
Bill Thomas
Greg West
You can achieve it without implementing Comparable interface.
Simply use Collections.sort(List,Comparator) method.
sample code:
Collections.sort(l,new Comparator<MyLink>(){
#Override
public int compare(MyLink o1, MyLink o2) {
int result = o1.last.compareTo(o2.last);
if(result==0){
result=o1.first.compareTo(o2.first);
}
return result;
}
});
Note:
Never use build in class's name for your class that might sometime create confusion
Respect Java Naming convention.
I'd create a Person bean object which:
contains the firstname and surname, and
implements Comparable to sort on the surname
Then all you have to do is put all your Person objects in an ArrayList, and use Collections.sort() to get them in the right order.
You can have your class myLink implement Comparable interface. Then override compareTo() method as per your requirement.Then you can sort using Collections.sort(collection);
For more info read the documentation.
Also take care of Java naming conventions. myLink should be MyLink and so on...
This will sort the Collection of myLink . But if you want to sort your custom LinkedList class I would suggest create a method sort() in class LinkedList. In this method create a List of all your myLink instances (You have reference to the head). Then call Collections.sort() here and return Sorted Collection.
I need to compare two objects in insert method off the tree set. But i am unable to fathom out where and how to implement Comparable or Comparator. My code looks as follows:
This is my Node creation for the binary tree.
Node.java
public class Node {
private Object data;
private Node left, right;
//initial case when a Node of a binary tree gets created. both left and right subtrees point to null
public Node (){
left = right = null;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
}
This is my MyBinaryTree class where i need to implement insert method:
MyBinaryTree.java
public class MyBinaryTree implements Comparable<Node> {
Node root;
public MyBinaryTree(){
root = null;
}
void insert(Object x){
Node newrec = new Node(); //Node constructor gets called and sets up a root node with empty
//subtrees
newrec.setData(x);
if(root == null){
root = newrec;
}
else{
Node a,b;
a = b = root;
while(a!=null){
b=a;
if( ( newrec.getData() ).compareTo( a.getData() ) ) {
i am stuck here! how would i compare these objects using Comparable?
}
}
}
}
void inorder(Node root){
}
#Override
public int compareTo(Node o) {
// TODO Auto-generated method stub
int i = (o.)
return 0;
}
}
You need to be able to compare, not just nodes, but the data contained in those nodes. That means that your Node either needs to be limited to taking objects that are Comparable, or your tree needs to take a Comparator that it can use to compare them.
If you really want to support both, then when the time comes to do the comparison, if a Comparator has been provided, use its compare method, otherwise cast the data to Comparable<? super E> where E is the type of Node data (see below), and then use its compareTo method.
That brings me to the next point. Your Node class should probably not simply contain Object as its data, but instead be declared as Node<E> implements Comparable<Node<E>>, and then your tree can be declared as MyBinaryTree<E>. I would also change the constructor for Node to take the data as a parameter, rather than calling the setter immediately after creating one. There is no reason you would ever want to create a Node with no data.
I would strongly suggest looking through the source code for some of the generic collections in the java.util package, which comes with the JDK. In particular, I referred to the source of TreeMap.java to see how they handled both Comparable and non-Comparable elements, since the class isn't declared in such a way as to require the elements to be Comparable. (If they aren't, and there is no Comparator, a ClassCastException would occur where they try to cast the object to Comparable<? super K>.) Seeing how they have implemented similar code will be a great help to you. You may also want to review Java generics.
Please refer below code
package com.example.treeset;
import java.util.Comparator;
import java.util.TreeSet;
public class MyCompUser {
public static void main(String a[]){
//By using name comparator (String comparison)
TreeSet<Empl> nameComp = new TreeSet<Empl>(new MyNameComp());
nameComp.add(new Empl("Ram",3000));
nameComp.add(new Empl("John",6000));
nameComp.add(new Empl("Crish",2000));
nameComp.add(new Empl("Tom",2400));
for(Empl e:nameComp){
System.out.println(e);
}
System.out.println("===========================");
//By using salary comparator (int comparison)
TreeSet<Empl> salComp = new TreeSet<Empl>(new MySalaryComp());
salComp.add(new Empl("Ram",3000));
salComp.add(new Empl("John",6000));
salComp.add(new Empl("Crish",2000));
salComp.add(new Empl("Tom",2400));
for(Empl e:salComp){
System.out.println(e);
}
}
}
class MyNameComp implements Comparator<Empl>{
#Override
public int compare(Empl e1, Empl e2) {
return e1.getName().compareTo(e2.getName());
}
}
class MySalaryComp implements Comparator<Empl>{
#Override
public int compare(Empl e1, Empl e2) {
if(e1.getSalary() > e2.getSalary()){
return 1;
} else {
return -1;
}
}
}
class Empl{
private String name;
private int salary;
public Empl(String n, int s){
this.name = n;
this.salary = s;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public String toString(){
return "Name: "+this.name+"-- Salary: "+this.salary;
}
}
I'm creating a (atypical)tree in Java that will be composed of three classes: node, branch and leaf
Each node stores the branches it is connected to in a HashSet. The branch is supposed to lead to a descendent node or a leaf, but I'm not sure how to code that. Would I just have two separate variables, one Node and one Leaf in the branch class, along with two sets of getters and setters, even though I will never use both? Is there a best practice in this regard?
I was thinking maybe make node and leaf subclasses of the same superclass, but they have absolutely nothing in common in terms of code(i.e. different variable types, functions, etc.).
EDIT:
Node references branches and
each Branch references a Node or a Leaf
I'd probably go with something like this:
interface BranchDestination {
boolean isLeaf();
}
class Node implements BranchDestination {
private Set branches;
public boolean isLeaf() {
return false;
}
...
}
class Leaf implements BranchDestination {
public boolean isLeaf() {
return true;
}
...
}
class Branch {
BranchDestination destination;
...
}
I do like the idea of defining an interface for the leaf / node classes, and implement that interface in each. I would define a simple function in that interface (syntax might be wrong below, but it's pseduo-ish code):
interface BranchItem {
public object[] GetVals();
}
public class Branch
{
public BranchItem item;
}
public class Leaf implements BranchItem
{
private object myVal = <your data here>;
public object[] GetVals() {
return new object[] { myVal };
}
}
public class Node implements BranchItem
{
private myBranches[] = <List of Branches>;
public object[] GetVals() {
object[] myArray = new object[];
foreach (BranchItem b in myBranches)
{
myArray.addTo(b.item.GetVals());
}
return myArray;
}
}
When traversing your node, simply iterate over the Branches and call GetVals().
The Leaf class will simply returns it's stored value.
The Node Class will recursively loop over it's branches, calling GetVals() on each and add it to it's own returned array.
This is but a simple implementation. If you want sort order, handle collisions or duplicate data, or anything of that nature it could get more complicated.
Make the Leaf class with the basic information.
Make the Branch class which holds references to Leafs.
Make the Node class which holds references to Brahces.
Then try look up Recursion and how to use it to make such constructs :)
Here is my go at it. Though not very elegant, it gets the job done.
Here is the Leaf class:
public class Leaf {
private String text;
public Leaf(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setString(String newString) {
text = newString;
}
#Override
public String toString() {
return text;
}
}
And here is the Branch class:
public class Branch<T> {
private String text;
private HashSet<T> list;
public Branch(String text) {
this.text = text;
list = new HashSet<>();
}
public String getText() {
return text;
}
public void setText(String newText) {
text = newText;
}
public HashSet<T> getHashSet() {
return list;
}
public void setHashSet(HashSet<T> newList) {
list = newList;
}
public String getAllLeaves() {
StringBuilder sb = new StringBuilder();
sb.append(text).append("\n");
for(T t : list) {
sb.append("\t\t");
sb.append(t.toString()).append("\n");
}
return sb.toString();
}
#Override
public String toString() {
return text;
}
}
Lastly the Node class:
public class Node<T> {
private String text;
private HashSet<T> list;
public Node(String text) {
this.text = text;
list = new HashSet<>();
}
public String getText() {
return text;
}
public void setText(String newText) {
text = newText;
}
public HashSet<T> getHashSet() {
return list;
}
public void setHashSet(HashSet<T> newList) {
list = newList;
}
}
Little test program to try it out:
public class TreeConstruct {
public static void main(String[] args) {
Leaf l1 = new Leaf("Leaf 1");
Leaf l2 = new Leaf("Leaf 2");
Leaf l3 = new Leaf("Leaf 3");
Leaf l4 = new Leaf("Leaf 4");
Branch<Leaf> b1 = new Branch("Branch 1");
Branch<Leaf> b2 = new Branch("Branch 2");
Node<Branch> n1 = new Node("Node 1");
b1.getHashSet().add(l1);
b1.getHashSet().add(l2);
b1.getHashSet().add(l3);
b2.getHashSet().add(l4);
n1.getHashSet().add(b1);
n1.getHashSet().add(b2);
System.out.println(printNodeTree(n1));
}
public static String printNodeTree(Node<Branch> n) {
StringBuilder sb = new StringBuilder();
sb.append(n.getText()).append("\n");
for(Branch b : n.getHashSet()) {
sb.append("\t");
sb.append(b.getAllLeaves());
}
return sb.toString();
}
}
The output will be:
Node 1
Branch 1
Leaf 1
Leaf 3
Leaf 2
Branch 2
Leaf 4
Hope this helps!