I have a task where i have to create a recently used list in java. I'm a bit lost and I do not really know where to start. Please help! This is the code I have been given to start with:
public class RecentlyUsedList {
// Members (a.k.a. fields)
private String[] theItems;
private int noOfItems;
// Constructor
public RecentlyUsedList(int capacity) {
// Create the array with indicated capacity
// Initialize numberOfItems
}
// Public methods
public int getNoOfItems() {
}
public boolean isEmpty() {
// Is this list empty or not?
}
public String getItemAt(int index) {
// If index is out of range, return null
// Otherwise return a reference to the indicated item
}
public void addItem(String item) {
// 1. Check if the list contains this item; if so, remove it and pack
// 2. Check if the array needs resizing
// 3. Add the item to the list. Increment noOfItems.
}
public void removeItem(String item) {
// Check if the list contains this item; if so, remove it and call pack
// NB! use equals to compare Strings, e.g. str1.equals(str2)
}
public String toString() {
// Return a string of the form
// [1st item; 2nd item; ...]
}
// Private (helper) methods
private void pack(int index) {
// In a loop, starting at "index", copy item at position+1 to position
// (if the items are stored in "reverse order")
// Decrement noOfItems.
}
private void resize() {
// Create a new, temporary, reference and a corresponding String-array
// Copy all item-references to the new array
// Let the "theList" reference the new array (i.e. theItems = temp)
}
}
Please does anyone have directions on how to start?
Giving you a head start by giving code for 3 methods. Rest you can attempt on your own.
// Public methods
public int getNoOfItems() {
return noOfItems;
}
public String getItemAt(int index) {
if (index >= noOfItems) {
return null;
} else {
return theItems[index];
}
}
public String toString() {
StringBuilder builder = new StringBuilder("[");
for (int i = 0; i < theItems.length; i++) {
if (theItems[i] != null) {
builder.append(theItems[i]).append(";");
}
builder.append("]");
return builder.toString();
}
Related
I have the following class;
public class RSSFeed implements Serializable {
private static final long serialVersionUID = 1L;
private int _itemcount = 0;
private List<RSSItem> _itemlist;
RSSFeed() {
_itemlist = new Vector<RSSItem>(0);
}
void addItem(RSSItem item) {
_itemlist.add(item);
_itemcount++;
}
public void removeItem(RSSItem item) {
_itemlist.remove(item);
_itemcount--;
}
public void shuffleList() {
Collections.shuffle(_itemlist);
}
public RSSItem getItem(int location) {
return _itemlist.get(location);
}
public int getItemCount() {
return _itemcount;
}
public void reverseList(){Collections.reverse(_itemlist);};
}
I can create an object of this class as follows;
public static RSSFeed feed;
Now, I want another object like public static RSSFeed **feed1**; where feed1 contains items 3 to 20 of the big object feed. How do I do this?
Thanks
If you need the top three from the List, you can iterate the List _itemlist and create a temporary List and return the temporary list.
public List<RSSItem> getTopThree() {
if(_itemlist != null){
List<RSSItem> temp = new ArrayList<RSSItem>();
for (RSSItem item : _itemlist) {
temp.add(item);
if(temp.size() == 3)
break;
}
return temp;
}
return null;
}
An optimisation would be to pre create and store the items as a field in the class RSSFeed.
According to #MouseEvents sugestion, you can also use sublist method of the ArrayList. See the code below.
public List<RSSItem> getTopThree() {
if (_itemlist != null) {
int end = _itemlist.size() < 3 ? _itemlist.size() : 3;
return _itemlist.subList(0, end);
}
return null;
}
Right now I am trying to create a circular list, where when I use hasNext() from an Iterator it should always return true. However right now it is returning that it is not a circular list, and I am also having problems printing out the values (in this example Strings) of the ArrayList. Here is the CircularList class I created, which has a inner Node class for the objects that are put into the list:
public class CircularList<E> implements Iterable{
private Node<E> first = null;
private Node<E> last = null;
private Node<E> temp;
private int size = 0;
//inner node class
private static class Node<E>{ //In this case I am using String nodes
private E data; //matching the example in the book, this is the data of the node
private Node<E> next = null; //next value
//Node constructors, also since in this case this is a circular linked list there should be no null values for previous and next
private Node(E data){
this.data = data;
}
}
//end of inner node class
public void addValue(E item){
Node<E> n = new Node<E>(item);
if(emptyList() == true){ //if the list is empty
//only one value in the list
first = n;
last = n;
}
else{ //if the list has at least one value already
//store the old first value
temp = first;
//the new first is the input value
first = n;
//next value after first is the old first value
first.next = temp;
//if after this there will be only two values in the list once it is done
if(size == 1){
last = temp;
}
//if the list is greater than one than the last value does not change, since any other values will be put before last in this case, and not replace it
//creating the circular part of the list
last.next = first;
}
size++;
}
public boolean emptyList(){
boolean result = false;
if(first == null && last == null){ //if there is no values at all
result = true;
}
return result;
}
#Override
public Iterator<E> iterator() {
// TODO Auto-generated method stub
return new CircularIterator<E>(); //each time this method is called it will be creating a new instance of my Iterator
}
}
Here is the Iterator class I am making:
public class CircularIterator<E> implements Iterator<E> {
#Override
public boolean hasNext() {
return false;
}
#Override
public E next() {
// TODO Auto-generated method stub
return null;
}
#Override
public void remove() {
// TODO Auto-generated method stub
}
}
and finally the Test class:
public class Test {
static CircularList<String> c = new CircularList<String>(); //in this case it is a string list
static Iterator it = c.iterator();
public static void main(String[]args){
c.addValue("Bob");
c.addValue("Joe");
c.addValue("Jaina");
c.addValue("Hannah");
c.addValue("Kelly");
Iterate();
for(String val : c){
System.out.println(val);
}
}
private static boolean Iterate(){
boolean result = false;
if(!it.hasNext()){
System.out.println("Not a circular list!");
}
else{
result = true;
}
return result;
}
}
Again I am trying to get it to always return true, I think the problem lies with my hasNext() method, but I am not completely sure.
The main problem with your approach is you are using static inner classes - this is not necessary. Making the outer class generic is sufficient. The generic parameter is then inherited by the inner classes and all sorts of issues disappear.
Implementing an Iterator properly is subtle.
public static class CircularList<E> implements Iterable<E> {
private Node first = null;
private Node last = null;
private int size = 0;
private class Node {
private E data;
private Node next = null;
private Node(E data) {
this.data = data;
}
}
public void addValue(E item) {
Node n = new Node(item);
if (emptyList()) {
//only one value in the list
first = n;
last = n;
} else { //if the list has at least one value already
//store the old first value
Node temp = first;
//the new first is the input value
first = n;
//next value after first is the old first value
first.next = temp;
//if after this there will be only two values in the list once it is done
if (size == 1) {
last = temp;
}
//if the list is greater than one than the last value does not change, since any other values will be put before last in this case, and not replace it
//creating the circular part of the list
last.next = first;
}
size++;
}
public boolean emptyList() {
boolean result = false;
if (first == null && last == null) { //if there is no values at all
result = true;
}
return result;
}
#Override
public Iterator<E> iterator() {
return new CircularIterator(); //each time this method is called it will be creating a new instance of my Iterator
}
private class CircularIterator implements Iterator<E> {
// Start at first.
Node next = first;
public CircularIterator() {
}
#Override
public boolean hasNext() {
// Stop when back to first.
return next != null;
}
#Override
public E next() {
if (hasNext()) {
E n = next.data;
next = next.next;
if (next == first) {
// We're done.
next = null;
}
return n;
} else {
throw new NoSuchElementException("next called after end of iteration.");
}
}
}
}
public void test() {
CircularList<String> c = new CircularList<>();
c.addValue("A");
c.addValue("B");
c.addValue("C");
c.addValue("D");
for (String s : c) {
System.out.println(s);
}
}
Your main code was essentially correct - all I did was remove the unnecessary generics parameters from the inner classes.
Note that the way you add node to the list means that the items come out backwards. You could adjust that in your addValue method quite easily.
You can simply use following for circular iteration. This Circular list behave as same as other java.util.Lists. But it's iteration is modified. You don't need to care about it's performance tuning additionally. Because it's super class (LinkedList) is already well tested and enough stronger to use.
`public class CircularList extends LinkedList {
#Override
public Iterator<E> iterator() {
return createIterator();
}
//create new iterator for circular process
private Iterator<E> createIterator() {
return new Iterator<E>() {
private int index = 0;
#Override
public boolean hasNext() {
//no elements when list is empty
return isEmpty();
}
#Override
public E next() {
E node = get(index);
//rotate index
index++;
if (index == size()) {
index = 0;
}
return node;
}
};
}
}`
This question already has answers here:
Java Printing Functions
(2 answers)
Closed 9 years ago.
I need help with these two functions print and printall which really do what the title of the functions says
// Prints a directory of all StockItems with their associated
// price, in sorted order (ordered by SKU).
public void printAll() {
}
// Prints a directory of all StockItems from the given vendor,
// in sorted order (ordered by SKU).
public void print(String vendor) {
}
Here is the full function below. DictionaryADT is a class that is used in implementing Hashtables and BST. The DictionaryADT just consists of functions. It has NOTHING to do with Map.
import data_structures.*;
import java.util.Iterator;
import java.util.Map;
public class ProductLookup {
DictionaryADT<String,StockItem> dictionary;
private int maxSize;
public ProductLookup(int maxSize, DictionaryADT<String,StockItem> dictionary) {
this(maxSize);
this.dictionary = dictionary;
}
// Constructor. There is no argument-less constructor, or default size
public ProductLookup(int maxSize) {
this.maxSize = maxSize;
}
// Adds a new StockItem to the dictionary
public void addItem(String SKU, StockItem item) {
dictionary.insert(SKU,item);
}
// Returns the StockItem associated with the given SKU, if it is
// in the ProductLookup, null if it is not.
public StockItem getItem(String SKU) {
if (SKU == null)
return null;
return dictionary.getValue(SKU);
}
// Returns the retail price associated with the given SKU value.
// -.01 if the item is not in the dictionary
public float getRetail(String SKU) {
if (!dictionary.contains(SKU))
return (float) -.01;
return getItem(SKU).getRetail();
}
public float getCost(String SKU) {
if (!dictionary.contains(SKU))
return (float) -.01;
return getItem(SKU).getCost();
}
// Returns the description of the item, null if not in the dictionary.
public String getDescription(String SKU) {
if (!dictionary.contains(SKU))
return null;
return getItem(SKU).getDescription();
}
// Deletes the StockItem associated with the SKU if it is
// in the ProductLookup. Returns true if it was found and
// deleted, otherwise false.
public boolean deleteItem(String SKU) {
if (SKU == null)
return false;
return dictionary.remove(SKU);
}
// Prints a directory of all StockItems with their associated
// price, in sorted order (ordered by SKU).
public void printAll() {
}
// Prints a directory of all StockItems from the given vendor,
// in sorted order (ordered by SKU).
public void print(String vendor) {
}
// An iterator of the SKU keys.
public Iterator<String> keys() {
return dictionary.keys();
}
// An iterator of the StockItem values.
public Iterator<StockItem> values() {
return dictionary.values();
}
}
Unfortunately it seems like java's Iterator cannot be sorted using built in functions as it is not a collection. You can, however, convert it to a List first, and then sort.
// Prints a directory of all StockItems with their associated
// price, in sorted order (ordered by SKU).
public void printAll() {
// Convert the iterator of SKU's to a List
List SKUList = new ArrayList();
Iterator<String> keyIt = dictionary.keys();
while( keyIt.hasNext() )
SKUList.add(it.next());
// Sort the SKU's
Collections.sort(SKUList);
// Print each item
for(int i=0; i<SKUList.size(); i++){
StockItem item = dictionary.getValue( SKUList.get(i) );
// Print what you want here
}
}
I am having frustrating trouble getting my ArrayList to initialize. I am getting an error at the line binaryTreeList.set(1, root); saying
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.set(Unknown Source)
at BinaryTreeADT.<init>(BinaryTreeADT.java:18)
at Driver.main(Driver.java:7)
I'm trying to implement a simple binary tree using an ArrayList and I'd like the "root" element to be at ArrayList position 1. For some reason, the size of the `binaryTreeList is not growing, despite adding nodes to all of them.
Here is my code in order of Driver, BinaryTreeADT and MyTreeNode
public class Driver {
public static void main(String[] args) {
MyTreeNode mtn = new MyTreeNode(3, 'R');
BinaryTreeADT bt = new BinaryTreeADT(mtn);
bt.printTree();
}
}
BinaryTreeADT:
import java.util.ArrayList;
import javax.swing.tree.TreeNode;
public class BinaryTreeADT {
private ArrayList<MyTreeNode> binaryTreeList;
private MyTreeNode nullNode = new MyTreeNode(true); //This creates a null node that initially populates the array.
//Constructor with no root
public BinaryTreeADT(){
binaryTreeList = new ArrayList<MyTreeNode>(10);
}
public BinaryTreeADT(MyTreeNode root){
binaryTreeList = new ArrayList<MyTreeNode>(10);
initializeList();
binaryTreeList.set(1, root);
}
private void initializeList(){
for (int i = 0; i < binaryTreeList.size(); i++){
binaryTreeList.add(nullNode);
}
}
public void add(){
}
public void printTree(){
for (int i = 0; i < binaryTreeList.size(); i++){
if (binaryTreeList.get(i) != null)
System.out.println(binaryTreeList.get(i).getNodeChar() + " | ");
}
}
}
MyTreeNode:
import java.util.Enumeration;
import javax.swing.tree.TreeNode;
public class MyTreeNode implements TreeNode {
private int nodeKey;
private char nodeChar;
private boolean isNull;
public MyTreeNode(int key, char letter){
nodeKey = key;
nodeChar = letter;
}
//Constructor for Null Node
public MyTreeNode(boolean setNull){
isNull = setNull;
}
public boolean isNull(){ //Tells if this is a null node
return isNull;
}
#Override
public Enumeration children() {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean getAllowsChildren() {
// TODO Auto-generated method stub
return false;
}
#Override
public TreeNode getChildAt(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int getChildCount() {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getIndex(TreeNode arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public TreeNode getParent() {
// TODO Auto-generated method stub
return null;
}
public int getNodeKey() {
return nodeKey;
}
public void setNodeKey(int nodeKey) {
this.nodeKey = nodeKey;
}
public char getNodeChar() {
return nodeChar;
}
public void setNodeChar(char nodeChar) {
this.nodeChar = nodeChar;
}
#Override
public boolean isLeaf() {
// TODO Auto-generated method stub
return false;
}
}
Reason is this line:
binaryTreeList.set(1, root);
Because size of binaryTreeList is zero . You have constructed the ArrayList and told it to have the initial Capacity to be 10 using constructor ArrayList(int initialCapacity) , But since nothing is inside ArrayList right now , so ArrayList#size() is returning as 0. That's why within your initializeList method the for loop is exited at very first iteration which is not initializing the binaryTreeList with 10 elements. So the size of binaryTreeList is again still 0. This is the reason that setting a value at index 1 which is not existing at all is throwing IndexOutOfBoundException.
You should instead define initializeList as:
private void initializeList(){
for (int i = 0; i < 10; i++){
binaryTreeList.add(nullNode);
}
}
You are attempting to set the element at position 1 when your ArrayList is empty:
binaryTreeList.set(1, root);
Instead just use:
binaryTreeList.add(root);
Your reference is out of bounds. You should set the 0th index to your root node. However, since your ArrayList is empty (size = 0), you need to actually add the new element, which will increment the size of the array.
binaryTreeList.add(root);
With arrays, indices start at 0, so the element at index 0 of an array is the first element, the element at index 1 is the second, etc. If you have an array of size n, the last element will be at index n-1.
Later, if you want to change an element at a certain index, you can set the 0th element to root:
binaryTreeList.set(0, root);
This will work provided the first argument (0 in this case) is less than or equal to the binaryTreeList.size()-1.
let's say I have this simple MyArray class, with two simple methods: add, delete and an iterator. In the main method we can see how it is supposed to be used:
public class MyArray {
int start;
int end;
int[] arr;
myIterator it;
public MyArray(){
this.start=0;
this.end=0;
this.arr=new int[500];
it=new myIterator();
}
public void add(int el){
this.arr[this.end]=el;
this.end++;
}
public void delete(){
this.arr[this.start]=0;
this.start++;
}
public static void main(String[] args){
MyArray m=new MyArray();
m.add(3);
m.add(299);
m.add(19);
m.add(27);
while(m.it.hasNext()){
System.out.println(m.it.next());
}
}
And then MyIterator should be implemented somehow:
import java.util.Iterator;
public class myIterator implements Iterator{
#Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}
#Override
public Object next() {
// TODO Auto-generated method stub
return null;
}
#Override
public void remove() {
// TODO Auto-generated method stub
}
}
MyIterator should iterate arr from MyArray class, from start to end values; both are also attributes of MyArray. So, as MyIterator should use MyArray attributes, how should MyIterator be implemented? Perhaps I can send the current object in the initialization:
it=new myIterator(this);
But I guess it's not the best soultion. Or maybe MyArray itself should implement Iterator interface? How is this solved?
EDIT:
Ok, thanks to everybody. This was a simple example of what I wnat to do, so don't care about fixed length array. Waht I really want to do is a circular FIFO, that's why start and end are the cursors.
This circular FIFO will be an array of pairs of ints with, e.g., size 300: int[][] arr=new int[300][2].
When iterating a circular array I have to take care if the counter arrives to the end and make it start from the beginning, so this is how I have solved it:
if (this.start >= this.end ) temp_end=this.end+this.buff.length;
else temp_end=this.end;
int ii;
int j=0;
int[] value=new int[2];
for(int i=this.start; i<temp_end; i++){
ii=i% this.arr.length;
value=this.buff[ii];
//do anything with value
}
But I would like to avoid worrying about these things and just iterate in a simple way, I can do this with iterator interface, but then I have 2 problems: the first one I already explained and has been solved by many answers, and the second one is that my array is made of pairs of ints, and I can't use iterator with primitive types.
Its very unusual to maintain an iterator as an instance variable of the class. You can only traverse the array once - probably not what you want. More likely, you want your class to provide an iterator to anyone that wants to traverse your array. A more traditional iterator is below.
Java 5+ code - I haven't tried to compile or run, so it may be contain errors (not near a dev machine right now). It also uses autobox'ing for converting Integer to int.
public class MyArray implements Iterable<Integer> {
public static class MyIterator implements Iterator<Integer> {
private final MyArray myArray;
private int current;
MyIterator(MyArray myArray) {
this.myArray = myArray;
this.current = myArray.start;
}
#Override
public boolean hasNext() {
return current < myArray.end;
}
#Override
public Integer next() {
if (! hasNext()) throw new NoSuchElementException();
return myArray.arr[current++];
}
#Override
public void remove() {
// Choose exception or implementation:
throw new OperationNotSupportedException();
// or
//// if (! hasNext()) throw new NoSuchElementException();
//// if (currrent + 1 < myArray.end) {
//// System.arraycopy(myArray.arr, current+1, myArray.arr, current, myArray.end - current-1);
//// }
//// myArray.end--;
}
}
....
// Most of the rest of MyArray is the same except adding a new iterator method ....
public Iterator<Integer> iterator() {
return new MyIterator();
}
// The rest of MyArray is the same ....
}
Also note: be careful of not hitting that 500 element limit on your static array. Consider using the ArrayList class instead if you can.
In my opinion it is better to implement MyArray as common Iterable object, so it can be used in a for statement.
My suggestion:
/**
* My array
*/
public class MyArray<TItem> implements Iterable<TItem>
{
/**
* Internal used iterator.
*/
private class MyArrayIterator<TItem> implements Iterator<TItem>
{
private MyArray<TItem> _array;
/**
* #param array The underlying array.
*/
public MyArrayIterator(MyArray<TItem> array)
{
this._array = array;
}
/**
* Gets the underlying array.
*
* #return The underlying array.
*/
public MyArray<TItem> getArray() {
return this._array;
}
#Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}
#Override
public TItem next() {
// TODO Auto-generated method stub
return null;
}
#Override
public void remove() {
// TODO Auto-generated method stub
}
}
public void add(int el){
// do add
}
public void delete(){
// do delete
}
#Override
public Iterator<TItem> iterator() {
// TODO Auto-generated method stub
return new MyArrayIterator<TItem>(this);
}
}
As I said you can use it in a for statement:
private static void test(MyArray<String> strArray)
{
for (String str: strArray) {
// do something
}
}
Iterator is an interface . Iterator<E> which means only Object can go here (E) .
Iterator<Integer> is legal but Integer<int> is not because int is primitive data type
You can change the array to the ArrayList and then iterate over this arraylist. I added getIterator() method that returns the arraylist.iterator() and test it in main() method
import java.util.ArrayList;
import java.util.Iterator;
public class MyArray {
int start;
int end;
ArrayList<Integer> arr;
public MyArray() {
this.start = 0;
this.end = 0;
arr = new ArrayList<Integer>(500);
}
public void add(int el) {
arr.add(el);
this.end++;
}
public void delete() {
arr.remove(arr.size()-1);
this.start++;
}
public Iterator<Integer> getIterator(){
return arr.iterator();
}
public static void main(String[] args) {
MyArray m = new MyArray();
m.add(3);
m.add(299);
m.add(19);
m.add(27);
Iterator<Integer> it = m.getIterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
My suggestion is to let MyArray implement the interface java.lang.Iterable and create an instance of an iterator per iterator() call (as an anonymous class). Then you can use an instance of MyArray directly in a foreach construct:
public class MyArray implements Iterable {
// ...
// Only arr is needed now as an instance variable.
// int start;
// int end;
int[] arr;
// myIterator it;
/**
* From interface Iterable.
*/
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
// The next array position to return
int pos = 0;
public boolean hasNext() {
return pos < arr.length;
}
public Integer next() {
if(hasNext())
return arr[pos++];
else
throw new NoSuchElementException();
}
public void remove() {
throw new UnsupportedOperationException();
}
}
}
}
Update: According to BertF's comment I updated my code to make it clear, that the only instance variable for class MyArray is now arr. The state for the iterator is now inside the anonymous Iterator implementation. So you can create multiple iterator instances which don't interfere each other.
EDIT: this does not work for arrays of primitive types:
you could use Arrays for this:
it = new Arrays.asList(arr).subList(start, end).iterator();
END OF EDIT
If you really want to implement your own iterator, I would suggest an internal class in this scenario. This way you can access MyArray.this from myIterator.
public class MyArray {
....
private class myIterator implements Iterator{
....
}
}
MyArray should implement the Iterator as it is also responsible for maintaining the array. Simple encapsulation principle.