I'm trying to define void add(T thing) method by using the inherited push method of a stack but Eclipse says the return type is incompatible with Vector<T>.add(T) and wants me to change the return type of add(T) to boolean which doesn't make sense.
Below is my code
public class ListStack<T> extends Stack<T> implements SomeList<T>{
Stack<T> stack1=new Stack<T>();
public ListStack(){//constructor
super();
stack1=new Stack<T>();
}
//add method
public void add(T something){
this.push(something);}
}
Here's my SomeList interface
public interface SomeList<T>{
public void add(T something);
public void take(T idx);
.
.
.
}
Well since you're holding an instance of Stack<T> as member you don't need to inherit from the very same class.
Remove the inheritance and use your member instead:
public void add(T something){
stack1.push(something);
}
If you no longer subclass Stack<T> your compiler shouldn't complain about the different return types of add(T) anymore.
I think you should have a look into the adapter pattern.
Here's how I would do it:
Interface
interface MyList<T> {
public void addFront(T thing);
public void remove(int pos);
public void removeEnd();
public T get(int pos);
public int length();
public boolean isEmpty();
}
Implementation
class MyListImpl<T> implements MyList {
Stack<T> mStack;
public MyListImpl() {
mStack = new Stack<T>();
}
public void addFront(T thing) {
mStack.push(thing);
}
public void remove(int pos) {
//mStack...
}
public void removeEnd() {
//mStack...
}
public T get(int pos) {
// return mStack...
}
public int length() {
// return mStack...
}
public boolean isEmpty() {
// return mStack...
}
}
Your Stack Class must be having the method add() with a return type of boolean
Stack class extends Vector class, which contains boolean add(E e). I think Eclipse confuses between the add method in Vector, and the add method in your SomeList interface.
Related
I'm trying out Interfaces in java and I want to implement a common interface for a really simple stack, with pop() and push() methods and an iterator.
The problem is that I don't know how to specify the iterator in the interface. No matter which way I try, I get
Main.java:32: error: for-each not applicable to expression type
for (Integer i : ss)
^
required: array or java.lang.Iterable
found: Stack<Integer>
The code is as follows:
interface Stack<T> {
boolean push(T t);
boolean pop();
//Iterator<T> iterator(); // How to indicate it needs, and will have, an iterator?
}
public class DynamicStack<T> implements Iterable<T>, Stack<T>
{
// implementation-specific variables go here
public DynamicStack() {
//...
}
public boolean push(T t) {
//...
}
public boolean pop() {
//...
}
private class StackIterator implements Iterator<T> {
DynamicStack<T> stk;
//...
// Iterator constructor
private StackIterator(DynamicStack<T> stk)
{
//...
}
public boolean hasNext()
{
//...
}
public T next() throws NoSuchElementException
{
//...
}
public void remove() throws UnsupportedOperationException
{
throw new UnsupportedOperationException(); // I chose not to implement this one
}
}
// Iterator method
public Iterator<T> iterator()
{
return new StackIterator(this);
}
}
public class StaticStack<T> implements Iterable<T>, Stack<T>
{
// implementation-specific variables go here
public StaticStack()
{
//...
}
public boolean push(T t)
{
//...
}
public boolean pop()
{
//...
}
private class StackIterator implements Iterator<T>
{
StaticStack<T> stk;
//...
private StackIterator(StaticStack<T> stk)
{
//...
}
public boolean hasNext()
{
//...
}
public T next() throws NoSuchElementException
{
//...
}
public void remove() throws UnsupportedOperationException
{
//...
}
}
// Iterator method
public Iterator<T> iterator()
{
return new StackIterator(this);
}
}
Main simply does this, after creating a few stacks of each type and adding a few elements:
public static void showStuff(Stack<Integer> ss)
{
for (Integer i : ss)
System.out.print(i+" ");
System.out.println();
}
In your test class, you are operating against Stack interface, so that is the one that needs to conform to Iterable. In this case it doesn't help if StaticStack or DynamicStack implement it if Stack does not.
To get Stack to be able to be used as Iterable just change your Stack to extend Iterable:
public interface Stack<T> extends Iterable<T> {
boolean push(T t);
boolean pop();
}
and
public class StaticStack<T> implements Stack<T>
and the code runs just fine:
public class Tester {
public static void main(String args[]) {
Stack<Integer> ss = new StaticStack<>();
for (Integer i : ss)
System.out.print(i+" ");
System.out.println();
}
}
You need you class to implement Iterable<T>, which has the iterator() method, which returns Iterator<T>.
I have following methods defined in interface
public interface Stack<T> {
void method1(T element);
T method2();
}
Class Implementing this interface implements these methods as follows
private List<T> elements;
#Override
public void method1(T element) {
elements.add(element);
}
#Override
public T method2() {
return elements.remove(elements.size() - 1);
}
With this I get following error for method1: Method does not override method from super class, while method2 works fine.
Any idea what am I doing wrong?
This works perfectly fine:
import java.util.ArrayList;
import java.util.List;
public class Main {
interface MyStack<T> {
void push(T item);
T pop();
}
static class MyStackImpl<T> implements MyStack<T> {
private List<T> items = new ArrayList<T>();
#Override
public void push(T item) {
items.add(item);
}
#Override
public T pop() {
return items.remove(items.size() - 1);
}
}
public static void main(String[] args) {
MyStack<Integer> stack = new MyStackImpl<Integer>();
stack.push(42);
System.out.println(stack.pop());
}
}
You need to add type parameter to the interface and to the class too:
public interface Stack<T> { // here it is: <T>
void method1(T element);
T method2();
}
public class Impl<T> implements Stack<T> { // and here too
private List<T> elements;
#Override
public void method1(T element) {
elements.add(element);
}
#Override
public T method2() {
return elements.remove(elements.size() - 1);
}
}
You just need to specify the interface's generic type interface Stack<T>.
public interface Stack<T> {
void method1(T element);
T method2();
}
And you also need to define the generic type in you implementation class YourStack<T>
class YourStack<T> implements Stack<T>{
private List<T> elements;
#Override
public void method1(T element) {
elements.add(element);
}
#Override
public T method2() {
return elements.remove(elements.size() - 1);
}
}
I am reading the book effective java by Joshua Bloch. on the item 16 of "favor composition over inheritance", he gives an example of using HashSet and querying how many elements have been added since it was created(not to be confused with current size, which goes down when an element is removed). he provided the following code and here the getAddCount return 6, which I can understand. This should return 3 actually. (this is because HashSet's addAll method is implemented on top of its add method)
import java.util.HashSet;
public class InstrumentedHashSet<E> extends HashSet<E> {
// The number of attempted element insertions
private int addCount = 0;
public InstrumentedHashSet() {
}
public InstrumentedHashSet(int initCap, float loadFactor) {
super(initCap, loadFactor);
}
#Override
public boolean add(E e) {
addCount++;
return super.add(e);
}
#Override
public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c);
}
public int getAddCount() {
return addCount;
}
public static void main(String[] args) {
InstrumentedHashSet<String> s = new InstrumentedHashSet<String>();
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
System.out.println(s.getAddCount());
}
}
Now he explains a way to fix this, using wrapper classes (composition and forwarding). here is where I am having hard time to understand. he provides the following two classes
public class ForwardingSet<E> implements Set<E> {
private final Set<E> s;
public ForwardingSet(Set<E> s) {
this.s = s;
}
public void clear() {
s.clear();
}
public boolean contains(Object o) {
return s.contains(o);
}
public boolean isEmpty() {
return s.isEmpty();
}
public int size() {
return s.size();
}
public Iterator<E> iterator() {
return s.iterator();
}
public boolean add(E e) {
return s.add(e);
}
public boolean remove(Object o) {
return s.remove(o);
}
public boolean containsAll(Collection<?> c) {
return s.containsAll(c);
}
public boolean addAll(Collection<? extends E> c) {
return s.addAll(c);
}
public boolean removeAll(Collection<?> c) {
return s.removeAll(c);
}
public boolean retainAll(Collection<?> c) {
return s.retainAll(c);
}
public Object[] toArray() {
return s.toArray();
}
public <T> T[] toArray(T[] a) {
return s.toArray(a);
}
#Override
public boolean equals(Object o) {
return s.equals(o);
}
#Override
public int hashCode() {
return s.hashCode();
}
#Override
public String toString() {
return s.toString();
}
}
AND
import java.util.*;
public class InstrumentedSet<E> extends ForwardingSet<E> {
private int addCount = 0;
public InstrumentedSet(Set<E> s) {
super(s);
}
#Override
public boolean add(E e) {
addCount++;
return super.add(e);
}
#Override
public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c);
}
public int getAddCount() {
return addCount;
}
public static void main(String[] args) {
InstrumentedSet<String> s = new InstrumentedSet<String>(
new HashSet<String>());
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
System.out.println(s.getAddCount());
}
}
how this works? In the main method, I create an instance of HashSet and using addAll method, I add all the elements of list. but the HashSet invokes its addAll method (which in turn uses its add method), which should be the same as in the first in correct example and I should get value of 6, however this gives me 3.
In
public class InstrumentedHashSet<E> extends HashSet<E> {
you're adding directly to the HashSet because the addAll() is delegating to the super implementation
InstrumentedHashSet<String> s = new InstrumentedHashSet<String>();
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
System.out.println(s.getAddCount());
The addAll() internally calls add() which defers to your #Override implementation of add() because of polymorphism
#Override
public boolean add(E e) {
addCount++;
return super.add(e);
}
that increments the count and prints 6 (3 + 1 + 1 + 1).
In
public class InstrumentedSet<E> extends ForwardingSet<E> {
you are adding to
private final Set<E> s;
because the addAll() is delegating to it, so
public static void main(String[] args) {
InstrumentedSet<String> s = new InstrumentedSet<String>(
new HashSet<String>());
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
System.out.println(s.getAddCount());
}
and prints 3. Here the add() is being called on the Set<E> s, not on your instance.
The conclusion is that if you are inheriting, you need to understand the side-effects. Do the super method calls invoke any other method calls internally? If so, you need to act appropriately.
Inheritance (start from bottom)
s.add() // s is your InstrumentedHashSet instance, because of polymorphism (inheritance), this adds to the count
this.add() // this is the internal call inside the HashSet#addAll()
super.addAll(...) // this calls the HashSet implementation of addAll which calls add() internally
s.addAll(Arrays.asList("Snap", "Crackle", "Pop")); // s is your InstrumentedHashSet instance
Composition
this.add() // this is the internal call to add() inside the Set implementation
s.addAll() // s is the Set<E> instance
super.addAll(...) // this calls the ForwardingSet implementation of addAll()
s.addAll(Arrays.asList("Snap", "Crackle", "Pop")); // s is your InstrumentedSet instance
InstrumentedSet#getAddCount() returns 6 because the size of the array (3) is added twice!
//InstrumentedSet
public boolean addAll(Collection<? extends E> c) {
addCount += c.size(); //here
return super.addAll(c); //and here!
}
super.addAll(c); calls the add() Method.
More detailed:
InstrumentedSet#addAll -> ForwardingSet#addAll (because of super.addAll) -> HashSet#addAll() (because this is what you give it in the main) -> InstrumentedSet#add (because of polymorphism)
If you want a fix: remove addCount += c.size();
InstrumentedSet#addAll returns 3 because it calls this:
InstrumentedSet#addAll() (adds 3) -> ForwardingSet#addAll (because of super) -> HashSet#addAll (because forwardingset has a field of type HashSet) -> HashSet#add
Very simple question, Im implementing a array enumeration class but cannot remember how to get the correct type back on the nextElement() method. The code is as follows...
public class ArrayEnumeration<Object> implements Enumeration<Object> {
private Object[] data;
private int n = 0;
public ArrayEnumeration(Object[] data) {
this.data = data;
}
#Override
public boolean hasMoreElements() {
return n < data.length;
}
#Override
public Object nextElement() {
n++;
return data[n - 1];
}
}
so object returned from the nextElement method should be the type that was defined when the class was created. I just cannot remember how to do it. So annoying!!!
Many thanks in advance.
Check out the source code of java.util.List for an example:
public interface List<E> extends Collection<E> {
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/List.java
Your methods then use the generic type:
public boolean add(E e);
public E get(int index);
All from the source of the java.util.List..
So in your case:
public class ArrayEnumeration<E> implements Enumeration<E> {
...
#Override
public E nextElement() {
n++;
return data[n - 1];
}
}
Use a type parameter:
public class ArrayEnumeration<T>
implements Enumeration<T>
{
private T[] data;
public ArrayEnumeration(T[] data)
{
this.data = data;
}
// ...
public T nextElement() {}
}
Also, you should consider using Iterator instead. But in any event, arrays implement Iterable, so why are you doing this?
I have problem with sets. Required java.lang.String found String...
What can i do there?
public interface Node {
public <V> V get();
public <V> void sets(V value);
}
public enum MIBNodes implements Node {
TEST {
private String e;
#Override
public String get() {
return "aa";
}
#Override
public <String> void sets(String value) {
e=value;
}
};
};
UPDATE
Each enum instance like TEST , TEST1 ... may have different type.. String, Integer or anyother... So public enum MIBNodes implements Node { cant become public enum MIBNodes implements Node<String> {
This is the Problem:
#Override
public <String> void sets(String value) {
^^^^^^
e=value;
}
Here, String is a type variable (a re-definition of V), not a java.lang.String. And I don't really think you can fix that without changing your design:
public interface Node<V> {
public V get();
public void sets(V value);
}
And in case you want your enum to be generic : that's impossible. Different enum items can't implement the same interface with different generic parameters.