Declared a List, Implement as LinkedList, cannot use getLast() method - casting

I'm tried to create a linkedlist like below
List<Integer> list = new LinkedList<>();
int i = list.getLast();
But when I use getLast() method from LinkedList class, it reports "cannot find symbol "method getLast()"".
It appears that, since getLast() only exists in LinkedList class, and I declared list as a List, so I cast it into a more general form and lost some function.
But I'm curious how Java find a method name? Since I instantiate it as a LinkedList, can't it find this method in instantiated class?
Is there any documents I can read about

The problem is that the List interface does not expose a getLast() method, which is particular to the implementation LinkedList. You have several options here. If you want to declare your List as just that, then you may cast the linked list variable before calling getLast():
List<Integer> list = new LinkedList<>();
list.add(1);
int i = ((LinkedList<Integer>)list).getLast(); // but make sure it's a linked list
Another option would be to just declare your list as a linked list:
LinkedList<Integer> list = new LinkedList<>();

Related

Nested class and constructor calling understanding

I'm currently having an assignment, in which i need to create a DATABASE class,
which contains a employees pointers array, and private inner class,
that defines employees linked list
the goal to accomplish here, according to the assignment, is working acording
to a DB_TYPE defined constant.
when DB_TYPE = 0 i need my class methods to work with the employees pointers array,
when DB_TYPE = 1 i need my class methods to work with the employees linked list.
Therefore, i need two things:
1. Understanding constructor calling -
When i construct a new DATABASE object, for example with no paramaters,
the default constructor is called.
How do i call the linked list inner constructor to construct a Node, from the constructor itself?
2. Working according to the DB_TYPE constant -
I Suppose that's less of a trouble, as i can set my methods to work with
two cases\or with 'if' conditions regarding each value of DB_TYPE.
but if that's not that simple, i'll be glad to get some advise\help on how to do so.
EDIT:
My Current code:
class DataBase {
public:
DataBase();
private:
Employee ** empArr; /*!< Employees pointers array */
unsigned int empCount;
Node head;
class Node{
public:
Node();
Node(Employee * emp, Node * next);
private:
Employee * emp; /*!< Employee Pointer */
Node * next; /*!< The next node (containing the next employee) */
};
};
Thanks,
Adiel
The Node node; has to come after the definition of class Node.
To invoke a non-default constructor of node when creating a Database you use the constructor initialization list:
Database::Database()
: head(foo, bar)
, empCount(0)
, empArr(nullptr)
{
}
You can and should initialize the other members in this list too. If the object needs complicated initialization you can write a function to do that; initializing via the constructor body should be a last resort. (well, a later resort, it's not a terrible thing).
Note that the order member objects are initialized is the order they appear in the class definition - not the order they appear in the constructor init list. So if, for example, your head's constructor argument had to be worked out from empArr, you would have to make sure that Node head; came after Employee **empArr;, and also you'd have to write a function to set up empArr so your list would look like
: empCount(5), empArr( allocate_emparr(5) ), head(empArr[0], nullptr)
Re. DB_TYPE. Since it is preprocessor you can do, wherever appropriate,
#if DB_TYPE
// code for processing linked list
#else
// code for processing pointers array
#endif
This is very powerful, although some people consider it ugly. It's be nicer to use a template instead, especially if the class definition can stay the same and it is only a small number of functions whose behaviour needs to change. However it is challenging to write the template version well if you have not used templates much before.
Example declarations (could be class members or free functions):
template<int N> void do_something(void);
template<> void do_something<0>(void) { /* process pointers array */ }
template<> void do_something<1>(void) { /* process linked list */ }
Usage:
void other_func(void)
{
do_something<DB_TYPE>();
}

C++: Custom 'List' Member Functions

I have an index table where every index contains a list of type 'entry', where entry is
class entry{
public:
string word;
vector<int> line_numbers;
}
List member functions such as 'push_back' and 'empty' are unrecognized by the compiler since the list is of a custom type. How should I format to make these work, short of expanding the 'entry' class to include modified list member functions? Is that even possible? For reference,
vector<list<entry> > table
is the index table, and
table[c]
is the index. I'm trying to use something akin to
table[c].empty()
to test if the list is empty.
You're mistaken. std::list<entry>::empty() works regardless of the definition of empty. push_back requires that you can copy (or move) an empty object, how else are you going to get it into the container?

How to make a node that would contain a list as well

I searched a lot to find useful content over this topic but invain. I have made a linked list that is working fine. Now, as an assigment, I am required to store some dictionary words given in a file "input.txt". It is mentioned that you have to do this assignment using 2-D linked lists i.e., making another linked list inside the node of the linked list. Which means every node of the linked list would now contain a list as well. This can aslo be done with vectors but I guess linked list might be more helpful.
Now Consider the code.
//In list.h
template <class T>
struct ListItem
{
T value;
ListItem<T> *next;
ListItem<T> *prev;
ListItem(T theVal)
{
this->value = theVal;
this->next = NULL;
this->prev = NULL;
}
};
template <class T>
class List
{
ListItem<T> *head;
public:
// Constructor
List();
// Destructor
~List();
}
I need to make a linked list inside the node So in "Struct ListItem" I am doing something like this:
List<T> dictionary;
But it is giving an error:
"ISO C++ forbids declaration of âListâ with no type"
Second, how would I start making another linked list inside the node. I mean suppose temp pointer points to head of the first linked list. How would I now make another node (that would belong to my 2nd linked list) inside this node. I guess may be by something like this:
temp->ListItem<T>* secondListNode = new ListItem<T>(item); // I don't know whether
//It would or not as I am stuck in the first part.
This has to be done using 2-D format so please just stick to the constraints. Any other Useful suggestion regarding this problem would be helpful.
Thanks in advance.
You have a circular dependency. If you only have a pointer to ListItem<T> in List<T>, then declare ListItem<T> first, then define List<T> and after that define the ListItem<T> class:
template<class T>
class ListItem;
template<class T>
class List
{
ListItem<T> *head;
// ...
};
template<class T>
class ListItem
{
// `dictionary` is not a pointer or a reference,
// so need the full definition of the `List<T>` class
List<T> dictionary;
// ...
};
As you refer to a dictionary, you may think about using a std::map instead.
for example:
std::map<std::string, std::list<std::string> >
if you are storing your values as std::string.
I'm not sure if I fully understand what you mean with "Which means every node of the linked list would now contain a list as well."
If you just want to have a list of lists of strings, you can easily instantiate this with your existing List data structure, thanks to the template feature:
List<List<std::string> > listOfLists;
Of course, you can still have your "1D-list" too:
List<std::string> otherList;
Normally, it's a bad idea to adapt data structures to local requirements, but instead try to use generic data structures in a more specialized way, like above the "list of lists". Do not implement a "list of lists" as a separate class, nor change your generic list to a 2D-list. It's just a "list of any type T", so T can also be a list again (and again, and again...).

Using generic ADTs

I have a design problem. I'm asked to plan a design for a certain problem, where I need a few lists, and also a queue (which I need to create by myself, STL isn't allowed). In order to make the implementation more efficient, I thought about creating a generic list as follows: Create a node which contains a pointer to 'Data', an empty class. Then, any class that I want to make a list or a queue of (is the last sentence grammatically correct?), I'll just make it a subclass of data. That's the only way to make a generic list (I think), as we are not allowed to use void*.
The problem begins when I want to use a certain method of a certain class in a certain list. I can't do that, since 'Data' doesn't know that function. Creating a virtual function in Data is counter-logical and ugly, and we're also not allowed to use any downcasting.
Is there a way to overcome the problem using generic ADTs? Or must I create specific lists?
Thank you very much!
edit: We are also not allowed to use templates.
About the list and the queue, maybe you can adopt the same approach taken by the STL: just create the list, and then stack, as an adaptor of the list in which you only push and pop from the end.
About those contraints, which seems to be draconian, don't I suppose that the objective is for you to use templates?
Instead of creating and empty class, which if does not contain any method does not serve you at all, use a template as in the following example:
template<typename T>
class List {
class Node {
public:
Node(T* d)
{ data.reset( new Data( d ) ); }
T * getData()
{ return data; }
Node * getSig()
{ return sig; }
private:
std::auto_ptr<T> data;
Node * sig;
};
List()...
// Lots of more things...
};
You can find more info here:
http://www.cplusplus.com/doc/tutorial/templates/
Hope this helps.

C++ inheritance designing a linked list

I wanted to make a linked list class ListList that inherits from a class List.
ListList uses functions from List, but has its own functions. It has its own start pointer that points to the beginning of the list, and its own Node struct that holds a different amount of elements.
But, it looks like, when one of List's functions are called from ListList, List uses it's own start pointer and Node. But I want ListList's start pointer and Node to be used.
Can someone help me figure this out?
I could post some code, but I don't know what part would be relevant...
this is the one I called List above
class LinkList
{
public:
LinkList(); //constructor that sets the start pointer to NULL, to show that the list is empty
~LinkList(); //destructor that deletes each node in the linked list
LinkList(const LinkList &original); //copy constructor
void addToken(string token); //creates a node with the given token and places it at the beginning of the linked list
string showList(); //returns a string of tokens, separated by commas and spaces
bool findToken(string token); //searches linked list for the given token, returns true if the token is in the list
string getToken(string word); //searches linked list for a token that begins with the given word.
//Returns the full token if there's a token that begins with the given word, else returns an empty string
void deleteList();
protected:
struct Node //each node of the linked list, held together by the next pointer
{
string token;
bool second_word; //tells whether or not there is a space within the token (a two-word keyword)
//This could be easily changed to an int that tells how many words are within the keyword (for multi-word keywords)
Node *next; //pointer to the next node of the linked list. NULL if there is no next node
};
Node *start; //pointer to the beginning of the linked list, and the last added node
bool twoWordToken(string token); //returns true if there is a space located within a token, meaning the token consists of two words.
};
This is the one I called ListList above
class LinkListList: public LinkList
{
public:
LinkListList(); //modified contructor initiates the pointers start and ptrNode
~LinkListList(); //modified destructor deletes all nodes and secondaryList nodes
LinkListList(const LinkListList &original); //copy constructor
bool addSubList(LinkList subList, string commandWord); //calls setPtrNode, then adds the given subList to that node
bool findSubToken(string commandWord, string token); //calls setPtrNode, then calls on that node's secondaryList's findToken function
//returns true if the findToken function returns true, else returns false
string showSubList(string commandWord); //returns a string of tokens, separated by commas and spaces, representing the subList of the given token
string getSubToken(string word, string commandWord); //searches commandWord's subList for a token that begins with the given word.
//Returns the full token if there's a token that begins with the given word, else returns an empty string
private:
struct Node //each node of the linked list, held together by the next pointer
{
string token;
bool second_word; //tells whether or not there is a space within the token (a two-word keyword)
LinkList secondaryList; //keeps a list of all related words
Node *next;
};
Node *start; //pointer to the beginning of the linked list
Node *ptrNode; //this pointer is used for the functions
void setPtrNode(string token); //sets ptrNode to point to the node containing the specified token. ptrNode is NULL if the token could not be found
};
Edit: I see.
Ideally, you'd have just one linked list implementation that can hold any kind of value, including — and here's the kicker — a compound data structure that has a linked list as one of its fields. In the code you have right now, the inheritance is actually unnecessary as far as I can tell, you're generally duplicating all the hard work of creating a linked list, and you're mixing the linked list data structure with your higher-level object representing the various lists of words.
Here is one possible way I might structure the data structures here:
The generic linked list:
template <typename T>
class LinkedList { ... };
A class that uses linked lists to represent whatever list of words you're making:
class TokenList {
struct Token {
string word;
LinkedList<string> related;
};
LinkedList<Token> list;
// Methods to add/search/remove tokens from the lists and sublists
};
(Also, I suspect the data structure you're actually seeking is a map, but that's another discussion.)
Looks like you're looking for a Has-A relationship and not an Is-A relationship.
I would suggest for your LinkListList to have a List of lists of the first type, instead of using inheritance.
I think your List class needs some virtual functions. It doesn't know anything about ListList, so it can hardly be expected to use the derived class's members.
A virtual function in a base class allows inheritors to provide an override of it. When the base class (or external callers seeing it as the base class) calls the function in a derived instance, it knows to look for that override in the derived class instead of using the one in the base class.
If you control the base List class (as opposed to a supplied framework class) you could restructure it to use virtual functions in key places so that the derived ListList class could redirect them to its own logic while still being accessible to code accessing it as a List--for example, so you could create a ListList and pass it to something expecting a List.
But if you can't change List and it doesn't already have virtual functions you can override, you may not be able to do it. You might have to look for a different (lower) base class, or create ListList (or LinkedList?) as a separate class rather than derived. It could provide a ToList() function to export its contents as a standard List (and a constructor taking a List and/or a From(List) function to import from a List back into a ListList). But it's probably more work to use it that way, depending on what you actually need to do with it that had you looking to derived from List in the first place.
Edited: With the code you've now posted, it looks like inheritance may not be what you actually need, after all, as #rmn points out. So while this answer hopefully explains a little about how virtual functions work (as applicable to question originally posed), it may not apply to what you're really trying to do with the two classes.