I've been working on trying to implement an immutable set from scratch, so I'm not using HashSet or java.util.Set
I have this method in my Empty class to add an element to an empty set:
public Set<T> add(T x) {
return new Element<T>(x, new Empty<T>());
}
And in another class called Element, I have the following constructor:
public Element(T element, Empty<T> empty) {
assert(element != null);
assert(empty != null);
this.element = element;
this.set = empty;
}
EDIT: here is my other Element constructor used for adding an element to a set.
public Element(T x, Set<T> set) {
this.element = x;
this.set = set;
}
But when I try to add an element it fails and the set is still empty.
I've used a similar code when creating an immutable Binary Search Tree and it worked fine so I assumed that I could do the same but for an immutable Set.
I was just wondering if the problem was with my add method or my constructor
Thank you
The size method:
for the Empty class
/**
* returns number of elements in the set
* #return size - number of elements in the set
*/
public int size(){
return -1;
}
for the element class:
#Override
public int size() {
if (set.isEmpty() == true) {
return -1;
} else {
return set.toList().size();
}
}
the toList() method:
#Override
public List<T> toList() {
List<T> list = new ArrayList<T>();
int i;
for(i = 0; i < set.size(); i++){
list.set(i, element);
}
return list;
}
reading over this part I realise that the problem with returning the size may be from the toList method I wrote, but I don't think that should have an effect on adding an element to the set?
toString - Element Class:
#Override
public String toString() {
return "Set = [" + set + "]";
}
toString - Empty class:
public String toString() {
return "";
}
And the JUnit Test for Add:
EDIT: realised that the set was immutable and so tried to make a new set that was equal to the empty set with the added value - to store the change but kept getting the same NullPointerException error.
#Test
public final void testAdd() {
Set<Integer> set1;
set1 = set.add(1);
int i = 20;
set.add(i);
assertSame("Last element should be the newly added name object", i, set.toList().get(set.size()-1));
assertEquals("Set size should be two", 2, set.size());
}
The assertSame gives a NullPointerException (so I'm guessing this means that the add didn't work and the set is still empty); and if I comment it out to test the next line the assertEquals says that set.size() is -1 (empty)
Almost everything in your existing code is flawed. Your Element's ctor does not make sense, size() and toList() are implemented in weird way, even the unit test is flawed in basic Java.
Some pseudo code
interface Set<T> {
Set<T> add(T v);
int size();
boolean contains(T v);
}
class Element<T> extends Set<T> {
T value;
Set<T> next;
public Element<T>(T element, Set<T> next) {...}
public Set<T> add(T value) {
if contains(value) { // already in set
return this;
}
return new Element(value, this);
}
public int size() {
return next.size() + 1;
}
public boolean contains(T value) {
return (this.value.equals(value) || next.contains(value));
}
}
public class Empty<T> extends Set<T> {
public Set<T> add(T value) {
return new Element(value, this);
}
public int size() {
return 0; // come on! 0 means empty, not -1!
}
public boolean contains(T value) {
return false;
}
}
Having reviewed my code, I realised where I was making the mistake.
Aside from the messy code in other areas, the add(T x) method was not working as expected due to the fact that I did not import the Empty or Element class to the Demo set or the JUnit test and, as mentioned by #shmosel, my toString method wasn't working properly because I did not include the element field and so was not going to output anything.
The following is my Demo code showing how I've added the import line. Furthermore, the constructor for Element works fine too. Again, I just needed to import the class for an Empty set for it to work.
package immutable.set;
import immutable.set.Empty;
public class DemoSet {
public static void main(String[] args) {
Set<Integer> set, set1, set2;
set = new Empty<Integer>();
System.out.println(set.isEmpty());
set1 = set.add(1).add(2);
set2 = set.add(3);
System.out.println(set1.toString());
System.out.println(set1.isEmpty());
System.out.println(set2.toString());
System.out.println(set2.isEmpty());
}
}
And it does print out the expected outcome.
Thank you for you help everyone.
I'm attempting to make a stack and am running into issues where every time I attempt to check an index value I'm getting a NullPointerException.
private E[] items;
public Stack(Class<E> type) {
E[] items = (E[]) new Object[10];
}
public boolean isEmpty(){
if(items[0] == null){
return true;
}
return false;
}
When I run
public static void main(String[] args) {
Stack<String> myStack = new Stack<>( String.class );
System.out.println(myStack.isEmpty());
}
I'm getting a NullPointerException at
if(items[0] == null)
during the call to isEmpty().
Obviously I know items[0] should be null at this point and want to be able to do things based on if it is null or not, in this case returning true since the stack is empty. How can I do this without getting a NullPointerException?
The line in the constructor
E[] items = (E[]) new Object[10];
creates a local variable but doesn't initialize your class field items. Use
items = (E[]) new Object[10];
The compiler will have raised a warning that items is not used so it is a good idea to pay attention to these warnings.
Also, when making generic classes as such, I'd recommend doing it slightly differently. Instead of passing the class as a constructor parameter, you can declare the class as generic and it will work the same.
public class Stack<E>
{
private E[] items;
public Stack() {
items = (E[]) new Object[10];
}
public boolean isEmpty(){
if(items[0] == null){
return true;
}
return false;
}
public E push(E item){
...
}
public E peek(){
...
}
.
.
.
}
Then your main class would look like:
Stack<String> myStack = new Stack<String>();
myStack.push("hi");
System.out.println(myStack.isEmpty());
This more closely emulates the conventions that java's built in generic classes have.
I've been trying to create a class which determines if a set of integers within an arraylist is a subset of another arraylist.
However, I receive an "error: incompatible types: ArrayList cannot be converted to int" whenever I try to compile and it appears that "return members" is causing it.
Could someone tell me what is wrong with "return members"? Any help would be greatly appreciated.
// Define the Set class
import java.util.ArrayList;
class Set {
private ArrayList<Integer> members;
public Set()
{
members = new ArrayList<Integer>();
}
public int getMembers()
{
return members;
}
public void setMembers()
{
this.members = members;
}
// toString() method
public String toString()
{
return "Set A is a subset of set B.";
}
// Return true if 'this' is a subset of 'set',
// otherwise return false.
public boolean isSubset(Set set)
{
for(int i = 0; i < this.members.size(); i++)
if(!members.contains(this.members.get(i)))
return false;
return true;
}
}
This method is your issue:
public int getMembers()
{
return members;
}
Wrong return type, change it to:
public ArrayList<Integer> getMembers()
{
return members;
}
Also your setMembers() does not do anything, set's itself to itself. It should be changed to:
public void setMembers(ArrayList<Integer> newMembers)
{
this.members = newMembers;
}
you are making mistake in first place.change return type in getMenbers(). you are returning an Object type and you specified it to return an int(primitive).
a typical method can only return the specified type. hope it helps
I'm getting the error "Iterator cannot be resolved to a type". I'm trying to take the storage class and add the code necessary to implement java's Collections class.
I dont think i'm allowed to import Iterator, i think i need to make my own.
public class storage {
private Object[] data = new Object[256];
// Don't allow access to anything not yet stored
private int nextEmptySlot = 0;
private int i=0;
public Object begin(){
return data[0];
}
public Object end(){
return data[nextEmptySlot];
}
//class Iterator() {
// public Storage data;
//}
public Iterator iterator() {
// returns a class that iterates over the data array
return new Iterator() {
public Object remove(){
for(int j=i+1 ; j<=nextEmptySlot-1 ; j++) {
this.data[j-1] = this.data[j];
}
return (this.data.data[i]);
}
public int hasNext(){
if(this.data.data[i+1] != null) return 1;
else return 0;
}
public Object next(){
i++;
if (hasNext()==1){
return this.data.data[i];
}
else if (hasNext()==0){
throw UnsupportedOperationException();
}
return this;
}
};
}
}
You need to import java.util.Iterator;
This code isn't even wrong; check out the Iterator methods:
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Iterator.html
Your Iterator does not implement the java.util.Iterator interface; using the same name doth not make it one.
Look at your method:
public int hasNext()
The java.util.Iterator hasNext() returns a boolean.
This is utterly wrong.
I need a queue with a fixed size. When I add an element and the queue is full, it should automatically remove the oldest element.
Is there an existing implementation for this in Java?
Actually the LinkedHashMap does exactly what you want. You need to override the removeEldestEntry method.
Example for a queue with max 10 elements:
queue = new LinkedHashMap<Integer, String>()
{
#Override
protected boolean removeEldestEntry(Map.Entry<Integer, String> eldest)
{
return this.size() > 10;
}
};
If the "removeEldestEntry" returns true, the eldest entry is removed from the map.
Yes, Two
From my own duplicate question with this correct answer, I learned of two:
EvictingQueue in Google Guava
CircularFifoQueue in Apache Commons
I made productive use of the Guava EvictingQueue, worked well.
To instantiate an EvictingQueue call the static factory method create and specify your maximum size.
EvictingQueue< Person > people = com.google.common.collect.EvictingQueue.create( 100 ) ; // Set maximum size to 100.
I just implemented a fixed size queue this way:
public class LimitedSizeQueue<K> extends ArrayList<K> {
private int maxSize;
public LimitedSizeQueue(int size){
this.maxSize = size;
}
public boolean add(K k){
boolean r = super.add(k);
if (size() > maxSize){
removeRange(0, size() - maxSize);
}
return r;
}
public K getYoungest() {
return get(size() - 1);
}
public K getOldest() {
return get(0);
}
}
There is no existing implementation in the Java Language and Runtime. All Queues extend AbstractQueue, and its doc clearly states that adding an element to a full queue always ends with an exception. It would be best ( and quite simple ) to wrap a Queue into a class of your own for having the functionality you need.
Once again, because all queues are children of AbstractQueue, simply use that as your internal data type and you should have a flexible implementation running in virtually no time :-)
UPDATE:
As outlined below, there are two open implementations available (this answer is quite old, folks!), see this answer for details.
This is what I did with Queue wrapped with LinkedList, It is fixed sized which I give in here is 2;
public static Queue<String> pageQueue;
pageQueue = new LinkedList<String>(){
private static final long serialVersionUID = -6707803882461262867L;
public boolean add(String object) {
boolean result;
if(this.size() < 2)
result = super.add(object);
else
{
super.removeFirst();
result = super.add(object);
}
return result;
}
};
....
TMarket.pageQueue.add("ScreenOne");
....
TMarket.pageQueue.add("ScreenTwo");
.....
public class CircularQueue<E> extends LinkedList<E> {
private final int capacity;
public CircularQueue(int capacity){
this.capacity = capacity;
}
#Override
public boolean add(E e) {
if(size() >= capacity)
removeFirst();
return super.add(e);
}
}
Usage and test result:
public static void main(String[] args) {
CircularQueue<String> queue = new CircularQueue<>(3);
queue.add("a");
queue.add("b");
queue.add("c");
System.out.println(queue.toString()); //[a, b, c]
String first = queue.pollFirst(); //a
System.out.println(queue.toString()); //[b,c]
queue.add("d");
queue.add("e");
queue.add("f");
System.out.println(queue.toString()); //[d, e, f]
}
I think what you're describing is a circular queue. Here is an example and here is a better one
This class does the job using composition instead of inheritance (other answers here) which removes the possibility of certain side-effects (as covered by Josh Bloch in Essential Java). Trimming of the underlying LinkedList occurs on the methods add,addAll and offer.
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
public class LimitedQueue<T> implements Queue<T>, Iterable<T> {
private final int limit;
private final LinkedList<T> list = new LinkedList<T>();
public LimitedQueue(int limit) {
this.limit = limit;
}
private boolean trim() {
boolean changed = list.size() > limit;
while (list.size() > limit) {
list.remove();
}
return changed;
}
#Override
public boolean add(T o) {
boolean changed = list.add(o);
boolean trimmed = trim();
return changed || trimmed;
}
#Override
public int size() {
return list.size();
}
#Override
public boolean isEmpty() {
return list.isEmpty();
}
#Override
public boolean contains(Object o) {
return list.contains(o);
}
#Override
public Iterator<T> iterator() {
return list.iterator();
}
#Override
public Object[] toArray() {
return list.toArray();
}
#Override
public <T> T[] toArray(T[] a) {
return list.toArray(a);
}
#Override
public boolean remove(Object o) {
return list.remove(o);
}
#Override
public boolean containsAll(Collection<?> c) {
return list.containsAll(c);
}
#Override
public boolean addAll(Collection<? extends T> c) {
boolean changed = list.addAll(c);
boolean trimmed = trim();
return changed || trimmed;
}
#Override
public boolean removeAll(Collection<?> c) {
return list.removeAll(c);
}
#Override
public boolean retainAll(Collection<?> c) {
return list.retainAll(c);
}
#Override
public void clear() {
list.clear();
}
#Override
public boolean offer(T e) {
boolean changed = list.offer(e);
boolean trimmed = trim();
return changed || trimmed;
}
#Override
public T remove() {
return list.remove();
}
#Override
public T poll() {
return list.poll();
}
#Override
public T element() {
return list.element();
}
#Override
public T peek() {
return list.peek();
}
}
Sounds like an ordinary List where the add method contains an extra snippet which truncates the list if it gets too long.
If that is too simple, then you probably need to edit your problem description.
Also see this SO question, or ArrayBlockingQueue (be careful about blocking, this might be unwanted in your case).
It is not quite clear what requirements you have that led you to ask this question. If you need a fixed size data structure, you might also want to look at different caching policies. However, since you have a queue, my best guess is that you're looking for some type of router functionality. In that case, I would go with a ring buffer: an array that has a first and last index. Whenever an element is added, you just increment the last element index, and when an element is removed, increment the first element index. In both cases, addition is performed modulo the array size, and make sure to increment the other index when needed, that is, when the queue is full or empty.
Also, if it is a router-type application, you might also want to experiment with an algorithm such as Random Early Dropping (RED), which drops elements from the queue randomly even before it gets filled up. In some cases, RED has been found to have better overall performance than the simple method of allowing the queue to fill up before dropping.
Actually you can write your own impl based on LinkedList, it is quite straight forward, just override the add method and do the staff.
I think the best matching answer is from this other question.
Apache commons collections 4 has a CircularFifoQueue which is what you are looking for. Quoting the javadoc:
CircularFifoQueue is a first-in first-out queue with a fixed size that replaces its oldest element if full.
A Simple solution, below is a Queue of "String"
LinkedHashMap<Integer, String> queue;
int queueKeysCounter;
queue.put(queueKeysCounter++, "My String");
queueKeysCounter %= QUEUE_SIZE;
Note that this will not maintain the Order of the items in the Queue, but it will replace the oldest entry.
As it's advised in OOPs that we should prefer Composition over Inheritance
Here my solution keeping that in mind.
package com.choiceview;
import java.util.ArrayDeque;
class Ideone {
public static void main(String[] args) {
LimitedArrayDeque<Integer> q = new LimitedArrayDeque<>(3);
q.add(1);
q.add(2);
q.add(3);
System.out.println(q);
q.add(4);
// First entry ie 1 got pushed out
System.out.println(q);
}
}
class LimitedArrayDeque<T> {
private int maxSize;
private ArrayDeque<T> queue;
private LimitedArrayDeque() {
}
public LimitedArrayDeque(int maxSize) {
this.maxSize = maxSize;
queue = new ArrayDeque<T>(maxSize);
}
public void add(T t) {
if (queue.size() == maxSize) {
queue.removeFirst();
}
queue.add(t);
}
public boolean remove(T t) {
return queue.remove(t);
}
public boolean contains(T t) {
return queue.contains(t);
}
#Override
public String toString() {
return queue.toString();
}
}
Ok, I'll throw out my version too. :-) This is build to be very performant - for when that matters. It's not based on LinkedList - and is thread safe (should be at least). FIFO
static class FixedSizeCircularReference<T> {
T[] entries
FixedSizeCircularReference(int size) {
this.entries = new Object[size] as T[]
this.size = size
}
int cur = 0
int size
synchronized void add(T entry) {
entries[cur++] = entry
if (cur >= size) {
cur = 0
}
}
List<T> asList() {
int c = cur
int s = size
T[] e = entries.collect() as T[]
List<T> list = new ArrayList<>()
int oldest = (c == s - 1) ? 0 : c
for (int i = 0; i < e.length; i++) {
def entry = e[oldest + i < s ? oldest + i : oldest + i - s]
if (entry) list.add(entry)
}
return list
}
}