Best way to implement retainAll() method - java

I've this custom class named MyAbstractList which implements MyList interface. Here's the code:
public abstract class MyAbstractList<E> implements MyList<E> {
protected int size = 0; // The size of the list
protected MyAbstractList() {
}
protected MyAbstractList(E[] objects) {
for (int i = 0; i < objects.length; i++)
add(objects[i]);
}
public void add(E e) {
add(size, e);
}
public boolean isEmpty() {
return size == 0;
}
public int size() {
return size;
}
public boolean addAll(MyList<E> otherList) {
for (E e : otherList) {
add(e);
}
if (otherList.size() > 0)
return true;
return false;
}
public boolean removeAll(MyList<E> otherList) {
boolean removed = false;
for (E e : otherList) {
if (remove(e) && !removed)
removed = true;
}
return removed;
}
public boolean remove(E e) {
if (indexOf(e) >= 0) {
remove(indexOf(e));
return true;
} else
return false;
}
/** Retains the elements in this list that are also in otherList
* Returns true if this list changed as a result of the call */
public boolean retainAll(MyList<E> otherList) {
}
}
How to implement the retainAll() method?
MyList interface:
public interface MyList<E> extends java.lang.Iterable<E> {
/** Add a new element at the end of this list */
public void add(E e);
/** Add a new element at the specified index in this list */
public void add(int index, E e);
/** Clear the list */
public void clear();
/** Return true if this list contains the element */
public boolean contains(E e);
/** Return the element from this list at the specified index */
public E get(int index);
/** Return the index of the first matching element in this list.
* Return -1 if no match. */
public int indexOf(E e);
/** Return true if this list contains no elements */
public boolean isEmpty();
/** Return the index of the last matching element in this list
* Return -1 if no match. */
public int lastIndexOf(E e);
/** Remove the first occurrence of the element o from this list.
* Shift any subsequent elements to the left.
* Return true if the element is removed. */
public boolean remove(E e);
/** Remove the element at the specified position in this list
* Shift any subsequent elements to the left.
* Return the element that was removed from the list. */
public E remove(int index);
/** Replace the element at the specified position in this list
* with the specified element and returns the new set. */
public Object set(int index, E e);
/** Return the number of elements in this list */
public int size();
/** Adds the elements in otherList to this list.
* Returns true if this list changed as a result of the call */
public boolean addAll(MyList<E> otherList);
/** Removes all the elements in otherList from this list
* Returns true if this list changed as a result of the call */
public boolean removeAll(MyList<E> otherList);
/** Retains the elements in this list that are also in otherList
* Returns true if this list changed as a result of the call */
public boolean retainAll(MyList<E> otherList);
/** Return an iterator for the list */
public java.util.Iterator<E> iterator();
}

If elements are not Comparable you can only search for elements of your list not present in the parameter.
public boolean retainAll(MyList<E> otherList) {
boolean changed = false;
for (int i = size() - 1; i >= 0; i--) {
Object obj = get(i);
if (!otherList.contains(obj)) {
remove(i);
changed = true;
}
}
return changed;
}
Note: this algorithm is done in O(n^2), if you have list of Comparable you can go to O(n log(n))
Second note: don't use an iterator to loop the list because a change on the content of the list may throw an Exception.
Comment on suggested edit by Saud: It is not necessary to update the size. This must be done by the method remove.

Related

cs 61b project1b Cannot resolve method get in Deque

I wrote these codes in Idea. The IDE throws "can't resolve method get in Deque.java" when I finished Palindrome.java. How come? I actually did that in the Deque.java. Although in the LinkedListDeque inherited the get() method from the origin LinkList.
I found another solution by changing
Deque stringDeque = wordToDeque(word);
to
LinkListDeque stringDeque = (LinkListDeque) wordToDeque(word);
But I am still curious about how cannot find get in Deque.
class diagram here
Deque interface
/** Create an interface in a new file named Deque.
* java that contains all of the methods that appear in both ArrayDeque and LinkedListDeque.
* #param <Item>
*/
public interface Deque<Item> {
int size = 0;
/** Adds an item of type T to the front of the deque. */
void addFirst(Item item);
/** Adds an item of type T to the back of the deque. */
void addLast(Item item);
/** Returns true if deque is empty, false otherwise. */
default boolean isEmpty() {
return size == 0;
};
/** Prints the items in the deque from first to last,
* separated by a space. Once all the items have been printed, print out a new line. */
void printDeque();
/** Removes and returns the item at the front of the deque. If no such item exists, returns null. */
Item removeFirst();
/** Removes and returns the item at the back of the deque. If no such item exists, returns null. */
Item removeLast();
/** Gets the item at the given index, where 0 is the front, 1 is the next item, and so forth.
* If no such item exists, returns null. Must not alter the deque! */
Item get(int index);
}
class LinkedLinkDeque.java
import java.util.LinkedList;
import java.util.NoSuchElementException;
/**
* Isn't this solution kinda... cheating? Yes.
*/
public class LinkedListDeque<Item> extends LinkedList<Item> implements Deque<Item> {
#Override
public void printDeque() {
System.out.println("dummy");
}
public Item getRecursive(int i) {
return get(i);
}
#Override
public Item removeFirst() {
try {
return super.removeFirst();
} catch (NoSuchElementException e) {
return null;
}
}
#Override
public Item removeLast() {
try {
return super.removeLast();
} catch (NoSuchElementException e) {
return null;
}
}
}
Palindrome.java
import java.util.Deque;
import java.util.LinkedList;
public class Palindrome {
/** Given a String, wordToDeque should return a Deque
* where the characters appear in the same order as in the String.
* #param word
*/
public Deque<Character> wordToDeque(String word) {
Deque<Character> stringDeque = new LinkedListDeque<>();
for (String s : word.split("")) {
stringDeque.addLast(s.charAt(0));
}
return stringDeque;
}
/** Return true if the given word is a palindrome, and false otherwise. */
public boolean isPalindrome(String word) {
if (word.length() == 0 || word.length() == 1) {
return true;
}
Deque stringDeque = wordToDeque(word);
int index = word.length() / 2;
for (int i = 0; i < index; i += 1) {
if (stringDeque.get(i) != stringDeque.get(word.length() - i - 1)) { return false; }
}
return true;
}
}
You have your own Deque interface but you are also working with the java.util.Deque interface. This can result in problems as the interface Deque is defined twice in different namespaces. Specially in your Palindrome.java file you are using the java.util.Deque interface because of the import java.util.Deque line at the top and NOT your Deque interface as you might expect.
Because of that you get the error message that the get(int) method is missing. That is correct, the java.util.Deque method does not define a get(int) method (but the java.util.List interface does).
Do not name classes with names which already exists in java. As you see that can result in naming conflict/issues.

Both methods have same erasure, yet overrides the other

I'm trying to implement a Queue but my method "enqueue(E e)" is giving me an error saying that the method clashes with the method in the Queue interface but neither override the other. What is going on?
Here is the Queue Interface
public interface Queue<E> {
/**
* Returns the number of elements in the queue.
*/
int size();
/**
* Tests whether the queue is empty.
*/
boolean isEmpty();
/**
* Inserts an element at the rear of the queue.
*/
void enqueue(E e);
/**
* Returns, but does not remove, the first element of the queue (null if empty).
*/
E first();
/**
* Removes and returns the first element of the queue (null if empty).
*/
E dequeue();
}
And here is the implementation
/**
* Implementation of the queue ADT using a fixed-length array.
* #param <E>
*/
public class ArrayQueue<E> implements Queue {
// instance variables
private E[] data;
private int f = 0;
private int sz = 0;
public static final int CAPACITY = 1000;
// Constructors
public ArrayQueue() {
this(CAPACITY);
}
public ArrayQueue(int capacity) {
data = (E[]) new Object[capacity];
}
// methods
/**
* Returns the number of elements in the queue
*/
public int size() {
return sz;
}
/**
* Tests whether the queue is empty.
*/
public boolean isEmpty() {
return sz == 0;
}
/**
* Inserts an element at the rear of the queue.
*/
public void enqueue(E e) throws IllegalStateException {
if (sz == data.length)
throw new IllegalStateException("Queue is full");
int avail = (f + sz) % data.length;
data[avail] = e;
sz++;
}
/**
* Returns, but does not remove, the first element of the queue (null if empty)
*/
public E first() {
if (isEmpty())
return null;
return data[f];
}
/**
* Removes and returns the first element of the queue (null if empty)
*/
public E dequeue() {
if (isEmpty())
return null;
E answer = data[f];
data[f] = null;
f = (f + 1) % data.length;
sz--;
return answer;
}
}
I've tried removing the "throws new IllegalStateError" and copy and pasting to make sure the spelling was the same. I can't figure out what the problem is. Both of these code fragments come straight out of a book...

can anyone help me with the sorting using compare to in array list?

Hi guys I am making an inventory program and I am having trouble with the stockItem sorting method.which i need to use compareto to solve it.
This is my code so far. Please scroll to the bottom to see what I'm talking about.
public class Inventory {
private ArrayList<StockItem> stock;
public Inventory() {
stock = new ArrayList<StockItem>();
}
public void addStockItem(StockItem item) {
stock.add(item);
}
public int size() {
return stock.size();
}
public String toString() {
String result = "";
for(StockItem item: stock)
result+=item.toString()+"\n";
return result;
}
public boolean isValidIndex(int index) {
return index >=0 && index < stock.size();
}
/**
*
* #param index
* #return null if index is not valid, otherwise
* return item at that index
*/
public StockItem getItem(int index) {
if (index < 0 || index >= this.stock.size())// check if this index exists
return null; // removes the item the from stock and returns it
else
return this.stock.get(index);
}
/**
*
* #param index
* #return null if index is invalid, otherwise remove item at the given
* index and return the removed item.
*/
public StockItem remove(int index) {
if (index < 0 || index >= this.stock.size()) // check if this index exists
return null; // removes the item the from stock and returns it
else
return this.stock.remove(index);
}
/**
* sort, using {#link StockItem#compareTo(StockItem)}
* cannot use built-in sort method from java
*/
public void sort() {
}
I guess that you want to order your items by their sizes. You may use any existing algorithm for sorting such as selection sort, insertion sort or bubble sort. Furthermore, it is possible to use the Java built-in method from Collections module which is much faster and easier to implement. You may use Collections.sort() method given that your class is implementing Comparable interface and its abstract method compareTo(). You can implement comapreTo() method manually or just use Integer class to do so. I used the second approach. I am building a StockItem class with the necessary methods and fields you need to sort. Your code for Inventory should look like this:
import java.util.ArrayList;
import java.util.Collections;
public class Inventory {
private ArrayList<StockItem> stock;
public Inventory() {
stock = new ArrayList<StockItem>();
}
public void addStockItem(StockItem item) {
stock.add(item);
}
public int size() {
return stock.size();
}
public String toString() {
String result = "";
for(StockItem item: stock)
result+=item.toString()+"\n";
return result;
}
public boolean isValidIndex(int index) {
return index >=0 && index < stock.size();
}
/**
*
* #param index
* #return null if index is not valid, otherwise
* return item at that index
*/
public StockItem getItem(int index) {
if (index < 0 || index >= this.stock.size())// check if this index exists
return null; // removes the item the from stock and returns it
else
return this.stock.get(index);
}
/**
*
* #param index
* #return null if index is invalid, otherwise remove item at the given
* index and return the removed item.
*/
public StockItem remove(int index) {
if (index < 0 || index >= this.stock.size()) // check if this index exists
return null; // removes the item the from stock and returns it
else
return this.stock.remove(index);
}
/**
* sort, using {#link StockItem#compareTo(StockItem)}
* cannot use built-in sort method from java
*/
public void sort() {
Collections.sort(stock);
}
}
and your code for StockItem class should be similar to the following:
public class StockItem implements Comparable<StockItem>{
private int size;
public void setSize(int size) {
this.size = size;
}
public int getSize() {
return this.size;
}
public Integer getSizeNonPrimativeInt() {
return new Integer(this.getSize());
}
#Override
public int compareTo(StockItem item) {
return this.getSizeNonPrimativeInt().compareTo(item.getSizeNonPrimativeInt());
}
}
Hope this help ;)
You have not pasted your code for StockItem class. So I assume a sample class below and you can change your code accordingly. Lets assume your StockItem class like below:
class StockItem{
private String itemName;
private double itemPrice;
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public double getItemPrice() {
return itemPrice;
}
public void setItemPrice(double itemPrice) {
this.itemPrice = itemPrice;
}
}
You mentioned you cannot use in-built sort() method from Collections, but I guess you might be pointed out you cannot use sort() method just because it sorts not the way you wanted? You need to define a comparator object with your custom sorting criteria and pass it to your in-built sort() method.
public class Inventory {
private ArrayList<StockItem> stock;
//-- your other code segments
static class ListComparator implements Comparator<StockItem>{
#Override
public int compare(StockItem o1, StockItem o2) {
if(o1.getItemName().compareTo(o2.getItemName())>0){
return 1;
}
else if(o1.getItemName().compareTo(o2.getItemName())<0){
return -1;
}
else
return 0;
}
}
public void sort() {
Collections.sort(stock, new ListComparator());
}
}

How to use an iterator in an implemented Queue

I have a task to code the below class ... I have a problem in iterator() method
I have many errors in it , I do not know how to do to correct it .. Can you suggest a way to correct the code under iterator() method ... You can as well see the other parts of the class ...I put the comments from eclipse next to each infected line.. thanks
package queue;
import java.util.*;
public class FifoQueue<E> extends AbstractQueue<E> implements Queue<E> {
private QueueNode<E> last;
private int size;
public FifoQueue() {
}
/**
* Returns an iterator over the elements in this queue
* #return an iterator over the elements in this queue
*/
public Iterator<E> iterator() {
QueueNode<E> position =last;
Iterator itr = position.iterator(); // The method iterator() is //undefined for the type FifoQueue.QueueNode<E>- Iterator is a raw type. References //to generic type Iterator<E> should be
parameterized
while(itr.hasNext){ // hasNext cannot be resolved or is not a field
int object=itr.next(); //Type mismatch: cannot convert from Object to int
return object; //Type mismatch: cannot convert from int to Iterator<E>
}
}
/**
* Returns the number of elements in this queue
* #return the number of elements in this queue
*/
public int size() {
return size;
}
/**
* Inserts the specified element into this queue, if possible
* post: The specified element is added to the rear of this queue
* #param x the element to insert
* #return true if it was possible to add the element
* to this queue, else false
*/
public boolean offer(E x) {
QueueNode<E> q = new QueueNode<E>(x);
if(last!=null){
q.next=last.next;
last.next=q;
return true;
} else {
return true;
}
}
/**
* Retrieves and removes the head of this queue,
* or null if this queue is empty.
* post: the head of the queue is removed if it was not empty
* #return the head of this queue, or null if the queue is empty
*/
public E poll() {
if( last==null){
return null;
}
QueueNode<E> n=last.next;
last.next=last.next.next;
size=size-1;
return n.element;
}
/**
* Retrieves, but does not remove, the head of this queue,
* returning null if this queue is empty
* #return the head element of this queue, or null
* if this queue is empty
*/
public E peek() {
if(last==null){
return null;
}
QueueNode<E> n=last;
while(n.next !=null){
}
return n.element;
}
private static class QueueNode<E> {
E element;
QueueNode<E> next;
private QueueNode(E x) {
element = x;
next = null;
}
}
}
Your iterator() method needs to return an implementation of the Iterator<E> interface. You'd likely want to do this as a private inner class, so it has access to the queue fields.
The iterator class needs to keep the current position, and step through your nodes on calls to next().
You might want to implement fail-fast logic to prevent issues with updating the queue while iterating. Add a change counter to the queue, and increment on change (insert/remove). Remember the change counter at the time the iterator is created, and if different on a call to next(), throw ConcurrentModificationException.
This is a skeleton to get you started:
public Iterator<E> iterator() {
return new FifoIterator();
}
private final class FifoIterator implements Iterator<E> {
private QueueNode<E> curr;
FifoIterator() {
this.curr = FifoQueue.this.last;
}
#Override
public boolean hasNext() {
return (this.curr != null);
}
#Override
public E next() {
if (this.curr == null)
throw new NoSuchElementException();
this.curr = this.curr.next;
E e = this.curr.element;
if (this.curr == FifoQueue.this.last)
this.curr = null;
return e;
}
}

Return an iterator

Searching for info about the iterator, I found only examples that showed how to iterate over a collection, and not returning the Iterator, like I want to do.
I am practicing for the exam, so I'm trying out some programming excercises to prepare myself, and this one is about the iterator pattern.
I want to implement the getKnightPositionIterator, . You can see the code below. This code is not mine, I found this.
package iterator;
import java.util.*;
public class Position {
/** return an iterator that will return all positions
* that a knight may reach from a given starting position.
*/
public static Iterator<Position> getKnightPositionIterator(Position p) {
return null;
}
/** create a position.
* #param r the row
* #param c the column
*/
public Position(int r, int c) {
this.r = r; this.c = c;
}
protected int r;
protected int c;
/** get the row represented by this position.
* #return the row.
*/
public int getRow() { return r; }
/** get the column represented by this position.
* #return the column.
*/
public int getColumn() { return c; }
public boolean equals(Object o) {
if (o.getClass() != Position.class) { return false; }
Position other = (Position) o;
return r==other.r && c==other.c;
}
public int hashCode() {
// works ok for positions up to columns == 479
return 479*r+c;
}
public String toString() {
return "["+r+","+c+"]";
}
}
How ever, I figure that I have to create an Iterator to return, so, so far, this is my attemp.
public static Iterator<Position> getKnightPositionIterator(Position p) {
Iterator<Position> knightPosIter = Position.getKnightPositionIterator(p);
for(Iterator<Position> positions = knightPosIter; positions.hasNext(); ) {
//What should I write here?
}
return knightPosIter;
}
First, make your class implement Iterable interface
public class Position implements Iterable<Position>
and write the public Iterator<Positions> iterator(); method as outlined below instead of providing a static method in your example.
As you actually need to compute a collection of reachable positions in one way or another, you will need a structure to hold it. Any such structure will normally be iterable and, thus, will have an iterator method. So a lazy implementation could look like this:
#Override
public Iterator<Position> iterator()
{
// make sure this returns e.g. Collections.unmodifiableList
Collection<Position> positions = computeReachablePositions();
return positions.iterator();
}
In case you have some other structure to compute and store your positions that is not iterable (not advisable), implement an iterator from scratch as follows (an array of positions assumed):
#Override
public Iterator<Position> iterator()
{
// must be final to be accessible from the iterator below
final Position[] positions = computeReachablePositions();
return new Iterator<Position>() {
int index = 0;
#Override
public boolean hasNext()
{
return index < positions.length;
}
#Override
public Position next()
{
if (hasNext())
{
Position value = positions[index];
index++;
return value;
}
throw new NoSuchElementException("No more positions available");
}
#Override
public void remove()
{
throw new UnsupportedOperationException("Removals are not supported");
}};
}

Categories

Resources