I have a custom generic linked list class called SLL. For the purpose of my program SLL is going to hold Word objects. In my Word class I have implemented the comparable interface, and defined three comparators. When I go to compile I get an error when trying to sort the custom list, using Collections.sort(). I cannot for the life of me figure out why. I have included some code below. The error message states:
//There is no suitable method found for sort(SLL<Word>, java.util.Comparator<Word>)
private static SLL<Word> wordList = new SLL<Word>();
//methods to populate custom generic list
private void printDescending ()
{
Collections.sort(wordList, Word.frequencyComp1);
System.out.println("10 Most Frequent");
printer(false);
}
My class declaration for SLL and a couple methods are as follows:
public class SLL <T extends Comparable <T>>
{
private Node<T> head , tail;
private int currentSize;
public SLL ()
{
this.head = null;
this.tail = null;
this.currentSize = 0;
}
public void add (Node<T> entry)
{
if (head == null)
{
Node<T> temp = entry;
head = temp;
tail = temp;
currentSize++;
}
else
{
Node<T> temp = entry;
tail.setNext(temp);
tail = temp;
currentSize++;
}
}
Any and all help would be greatly appreciated, I am on the last phase of my program :(
https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#sort(java.util.List)
According to this, your list(SLL) must have a List interface.
private static SLL<Word> wordList = new SLL<Word>();
As per your code SLL is class and wordList is class object with the reference of word class.
If you want use the sort method of Collection class the wordList object must be collection type object like below:
List<SLL<Word>> wordList = new ArrayList<SLL<Word>>();
Related
An implementation of a graph node is as follows (I cannot change the implementation as it is from a coding website):
class Node {
public int val;
public List<Node> neighbors;
public Node(int _val, ArrayList<Node> _neighbors) {
val = _val;
neighbors = _neighbors;
}
}
If I pass a node to my copyGraph function below, I wouldn't be able to make a copy of that node by calling the Node constructor because I get
incompatible types: List cannot be converted to ArrayList
class Solution {
public Node copyGraph(Node node) {
Node n = new Node(node.val, node.neighbors);
//do some code
}
}
How else could I make a new Node with this implementation?
Problem
That API is poorly designed, FYI. The constructor should accept a List rather than ArrayList. Ideally that code would be:
public Node ( int _val , List < Node > _neighbors ) { … }
… or perhaps even the more general Collection if order were unimportant.
public Node ( int _val , Collection < Node > _neighbors ) { … }
Workaround
Two ways to work around that poor design: cast, or copy.
If you know for sure that your List object is actually an ArrayList, cast as shown in the correct Answer by coconan.
If you are not sure of the concrete implementation of your List object, construct a new ArrayList while passing your List.
Node n = new Node ( node.val, new ArrayList < Node > ( nodesList ) );
You can cast node.neighbors to ArrayList with (ArrayList<Node>) node.neighbors
class Solution {
public Node copyGraph(Node node) {
Node n = new Node(node.val, (ArrayList<Node>) node.neighbors);
//do some code
}
}
Problem Definition
I need a collection which has nodes and each node has a constant size partially filled array. Each array may contain different size as long as smaller than previously defined constant size. There will be list of these nodes.
For example :
When an element is needed to be added to the list , list adds an element at the first appropriate node which is not full. If i continuously add(1) , add(2) , add(3) , add(4) , add(1) , list will be demonstrated like this :
Suppose DEFAULT_NODE_CAPACITY = 3
node-0 -> "123"
node-1 -> "41"
When an element is needed to be removed from the list , list removes an element from the first appropriate node which contains and matched with given element. If i remove(1) from the list , list will be demonstrated like this :
node-0 -> "23"
node-1 -> "41"
What did I try ?
I have considered the using inner class which is static one , because node class should not access the fields and methods of outher class. All types must have been generic so I put the generic key value that is identical for each constructor.
Critical point was that I had to use AbstractList class in my custom collection.At this point I really confuse about what structure that i will be use for invocating node class which has partially fixed array.
Questions
How can I override AbstractList methods which conform my node inner class . When I read the Java API Documentation , for creating modifiable i just need to override
get()
set()
remove()
add()
size()
at this point , how can i override all of them efficiently by conforming my problem definition ?
What data type should I use for invocating Node<E> ? and How can implement it ?
How did I implement ?
package edu.gtu.util;
import java.util.AbstractList;
import java.util.Collection;
import java.util.List;
public class LinkedArrayList<E> extends AbstractList<E>
implements List<E> , Collection<E>, Iterable<E> {
public static final int DEFAULT_CAPACITY = 10;
public static final int CONSTANT_NODE_CAPACITY = 3;
/* Is that wrong ? , how to be conformed to AbstractList ? */
private Node<E>[] listOfNode = null;
/*---------------------------------------------------------*/
private int size;
private static class Node<E> {
private Object[] data;
private Node<E> next = null;
private Node<E> previous = null;
private Node( Object[] data , Node<E> next , Node<E> previous ) {
setData(data);
setNext(next);
setPrevious(previous);
}
private Node( Object[] data ) {
this( data , null , null );
}
private void setData( Object[] data ) {
this.data = data;
}
private void setNext( Node<E> next ) {
this.next = next;
}
private void setPrevious( Node<E> previous ) {
this.previous = previous;
}
private Object[] getData() {
return data;
}
private Node<E> getNext() {
return next;
}
private Node<E> getPrevious() {
return previous;
}
}
private void setSize( int size ) {
this.size = size;
}
public LinkedArrayList() {
super();
}
public LinkedArrayList( int size ) {
super();
setSize( size );
listOfNode = (Node<E>[]) new Object[size()];
}
public LinkedArrayList(Collection<E> collection ) {
super();
}
#Override
public E get( int i ) {
}
#Override
public boolean add(E e) {
return super.add(e);
}
#Override
public boolean remove(Object o) {
return super.remove(o);
}
#Override
public E set(int index, E element) {
return super.set(index, element);
}
#Override
public int size() {
return size;
}
}
First, you need to add a field to Node that tells you how many data items are stored in that node.
Then:
size has to iterate over the nodes and compute the sum of the sizes of the nodes. Or you can maintain a separate size, and update it with every add and remove.
add has to find the node where the item can be inserted. If there's room in that node, just add it there. If that node is full, you have to create a new node.
remove has to find the right node and remove the item from that node. If the node becomes empty, the node itself can be removed.
get has to iterate over the nodes, keeping track of how many items it skips over, until it find the node that must contain the node.
set - same as get, except that it replaces the item in addition to returning it
You'll find better descriptions in wikipedia: https://en.wikipedia.org/wiki/Unrolled_linked_list
This article also suggests an important optimization for add/remove.
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());
}
}
}
Im trying to add each node of a Binary Search Tree to an ArrayList in order, I currently have this code...
private ArrayList<String> toArray(TreeNode<Comparable> root)
{
ArrayList<String> array = new ArrayList<String>();
if(root!= null)
return null;
inorder(root.getLeft());
array.add(root.getValue());
inorder(root.getRight());
return array;
}
but i get this error from running it...
Error: BSTree.java:64: cannot find symbol
symbol : method add(java.lang.Comparable)
location: class java.util.ArrayList<java.lang.String>
thank you for any help.
Would the following Generic method work for you? I'm away from my compiler but solution should be something like this:
private <T extends Comparable<T>> ArrayList<T> toArray(TreeNode<T> root)
{
if(null == root)
return null;
ArrayList<T> array = new ArrayList<T>();
inorder(root.getLeft());
array.add(root.getValue());
inorder(root.getRight());
return array;
}
This TreeNode seems similar to the class in this webpage:
Some CS Class notes
I have used something like this
private void inorder(Node u){
if( tree.isLeaf(u) ){
arrayList.add(u);
}else{
Node v = tree.getLeft(u);
invorder(v);
arrayList.add(u);
v = tree.getRight(v);
invorder(v);
}