I have a code like the following.
public class DefaultIterator<E> implements Iterator<E> {
private E[] array;
private int i = 0;
public DefaultIterator(E[] array) {
this.array = array;
}
#Override
public boolean hasNext() {
return false;
}
#Override
public E next() {
return array[i++];
}
#Override
public void remove() {
}
}
// here is my execution.
public Iterator<String> createNewIterator(Iterator<String>... generalIterators) {
return new DefaultIterator<Iterator<String>[]>(generalIterators);
}
I am getting the compilation error at the execution code. can somebody explain why it is failing and how to fix it?
Thanks.
So the complaint is that none of the generic types match up between the field declaration, the constructor declaration, and the method declaration.
You want:
public Iterator<String> createNewIterator(String... generalIterators) {
return new DefaultIterator<String>(generalIterators);
}
Your return type is another one than expected! DefaultIterator<Iterator<String>[]> isn't compatible with Iterator<String> Choose DefaultIterator<Iterator<String>[]> as your return type, this should solve it.
Related
So I have created my own Set, which is just a regular set, but has additional functions (for example my set only stores absolute values).
Here is my Code:
import java.util.*;
public class SortedByAbsoluteValueIntegerSet<E> extends HashSet<E> {
private Set<Integer> mySet;
public SortedByAbsoluteValueIntegerSet() {
mySet = new HashSet<Integer>();
}
#Override
public int size() {
return mySet.size();
}
#Override
public boolean add(E e){
return mySet.add(Math.abs((Integer) e));
}
#Override
public boolean remove(Object o) {
return mySet.remove(o);
}
#Override
public boolean contains(Object o){
return mySet.contains(o);
}
#Override
public boolean addAll(Collection<? extends E> c) {
List<Integer> myList = new ArrayList<>();
for (Object e: c) {
myList.add(Math.abs((Integer) e));
}
return mySet.addAll(myList);
}
#Override
public String toString(){
return mySet.toString();
}
}
I had a test case in JUnit, which failed. Because there was some issue with my code. For demonstration purpose, and for me to explain my issue better I have created two functions, which show the problem well.
Here is the problem:
public static void testSortedByAbsoluteValueIntegerSet() {
Set<Integer> set1 = new SortedByAbsoluteValueIntegerSet();
Set<Integer> set2 = new HashSet<>();
set1.add(5);
set1.add(3);
set2.add(5);
set2.add(3);
String x = toString(set1); //x is ""
String t = toString(set2); //t is "3 5"
}
public static String toString(final Collection<Integer> collection) {
return String.join(" ", collection.stream()
.map(i -> Integer.toString(i))
.toArray(String[]::new));
}
So the problem arises in this line:
String x = toString(set1); //x is always an empty string
String t = toString(set2); //t works correctly
When I go through debugger I see that String x is always an empty String and String t works correctly. By the way set1 is representation of my created set and set2 is just a regular hashset.
The question is: how can I fix my SortedByAbsoluteValueIntegerSet class so that the toString() method worked fine with my own created set as well.
P.S I am new to streams and I don't really understand the problem, why does it happens.
It's because you're extending HashSet but also using an internal Set.
When adding, you're adding to the internal Set but when using collection.stream() it calls the inherited HashSet (which is empty).
Easiest for you I beleive would be to remove the internal 'mySet' and call the inherited methods in your overridden methods.
For instance, your add method would be
#Override
public boolean add(E e){
return super.add(Math.abs((Integer) e));
}
(and then you don't need to override size, remove, contains of toString or spliterator)
Full example:
import java.util.*;
public class SortedByAbsoluteValueIntegerSet extends HashSet<Integer> {
#Override
public boolean add(Integer e){
return super.add(Math.abs(e));
}
#Override
public boolean addAll(Collection<? extends Integer> c) {
List<Integer> myList = new ArrayList<>();
for (Integer e: c) {
myList.add(Math.abs(e));
}
return super.addAll(myList);
}
}
I think Tomas F gave better answer
Main problem in your set is using HashSet mySet as field and extending HashSet. In java better to use (field) composition instead of extending to add some functionality to your class. Here you tried use both - it's not a good idea.
Best decision is to use just composition and extending more general class, for example AbstractSet<Integer> and Set<Integer>:
import java.util.*;
public class SortedByAbsoluteValueIntegerSet extends AbstractSet<Integer>
implements Set<Integer>, java.io.Serializable {
private final Set<Integer> mySet;
public SortedByAbsoluteValueIntegerSet() {
mySet = new HashSet<>();
}
#Override
public Iterator<Integer> iterator() {
return mySet.iterator();
}
#Override
public int size() {
return mySet.size();
}
#Override
public boolean add(Integer e) {
return mySet.add(Math.abs(e));
}
#Override
public boolean remove(Object o) {
return mySet.remove(o);
}
#Override
public boolean contains(Object o) {
return mySet.contains(o);
}
#Override
public boolean addAll(Collection<? extends Integer> c) {
List<Integer> myList = new ArrayList<>();
for (Integer e : c) {
myList.add(Math.abs(e));
}
return mySet.addAll(myList);
}
#Override
public String toString() {
return mySet.toString();
}
}
in this case you don't have to implement spliterator, because Set has default implementation using this keyword (which is refer to your set as a Collection)
but also you can implement spliterator in your class (but using such extends and internal Set fields are the bad practice. Also, it's better to get rid of type parameter E and casting elements to Integer:
import java.util.*;
public class SortedByAbsoluteValueIntegerSet extends HashSet<Integer> {
private Set<Integer> mySet;
public SortedByAbsoluteValueIntegerSet() {
mySet = new HashSet<>();
}
#Override
public int size() {
return mySet.size();
}
#Override
public boolean add(Integer e){
return mySet.add(Math.abs(e));
}
#Override
public boolean remove(Object o) {
return mySet.remove(o);
}
#Override
public boolean contains(Object o){
return mySet.contains(o);
}
#Override
public boolean addAll(Collection<? extends Integer> c) {
List<Integer> myList = new ArrayList<>();
for (Integer e: c) {
myList.add(Math.abs(e));
}
return mySet.addAll(myList);
}
#Override
public String toString(){
return mySet.toString();
}
#Override
public Spliterator<Integer> spliterator() {
return mySet.spliterator();
}
}
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>.
Normally when you implement a generic, you have some type T that you want to generalize. I want to write a class that generalizes a HashSet<T>.
I'm trying to write this the following way, but it's not the correct syntax or maybe it's not supported:
public class PermutationHelper<T> implements Iterable<T> {
private HashSet<T> m_set;
private long numberOfPermutations;
private boolean includeEmptyPermutationAsOutput = false;
public PermutationHelper(HashSet<T> set) {
m_set = set;
numberOfPermutations = 2 ^ set.size();
}
public void setIncludeEmptyPermutationAsOutput(boolean value) {
includeEmptyPermutationAsOutput = value;
}
#Override
public Iterator<T> iterator() {
Iterator<T> it = new Iterator<T>() {
long currentIndex = (includeEmptyPermutationAsOutput ? 0 : 1);
#Override
public boolean hasNext() {
return currentIndex < numberOfPermutations;
}
#Override
public T next() {
HashSet<T> result = new HashSet<T>();
return result; // expects T, but is a HashSet<T>..
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
};
return it;
}
}
I want the Iterator to give me all subsets of the passed-in HashSet<T>.
You can easly do
public class PermutationHelper<T extends HashSet<T>> implements Iterable<T>
in order to 'force' the generic type to be an HashSet or a subtype of a HashSet
What you want is simply
public class PermutationHelper<T> implements Iterable<HashSet<T>>
Your class is generic. You choose to name its generic type T. And it implements Iterable<HashSet<T>>, which means it must have a method
public Iterator<HashSet<T>> iterator()
I want to create my own implementation of ArrayList in java, that can listen when the list is changing and to do action when this happens.
From what I have read, I understand that I can't extend ArrayList and then add listener.
I want to use MyList in class as a variable with public modifier, so users can change it directly and to be done action when he changes it.
class MyList extends ArrayList<object>.... { ... }
class UseOfMyList {
public MyList places = new MyList<Object>();
places.add("Buenos Aires");
//and to be able to do that
List cities = new ArrayList<Object>();
cities.add("Belmopan");
places = cities;
So how to create and when do add,remove or pass another list to MyList an action to be performed?
You're not going to be able to do this by extending ArrayList, as it has no built-in notification mechanism (and, further, because it is has been declared final and thus cannot be extended). However, you can achieve your desired result by creating your own List implementation and adding your "listener" functionality vis a vis the add() and remove() methods:
class MyList<T>{
private ArrayList<T> list;
public MyList(){
list = new ArrayList<>();
...
}
public void add(T t){
list.add(t)
//do other things you want to do when items are added
}
public T remove(T t){
list.remove(t);
//do other things you want to do when items are removed
}
}
Old question, I know.
I apologize in advance for any bad formatting or missing lines of code. I'm a long-time user, first time contributor.
Anyhow, because of the removal of JavaFX from the JDK11, I was forced to write my own version of the ObservableList. Sure, we can plop JavaFX in with JMods or Maven, but it seems like a bit of an overkill just for the FXCollections.
Long Story made Short...er :)
I started out reading this old question and the answer didn't suit my needs fully, so I've added a custom event/listener class.
Figured I could share since this site has improved my coding 10 fold.
public static void main(String[] args) {
BackedList<String> list = new BackedList();
list.addListener(new BackedListListener<String>(){
#Override
public void setOnChanged(ListChangeEvent<String> event) {
if (event.wasAdded()) {
event.getChangeList().forEach(e->{
// do whatever you need to do
System.out.println("added: " + e);
});
}
if (event.wasRemoved()) {
// do whatever you need to dl
event.getChangeList().forEach(e->{System.out.println(e + " was removed");});
}
}
});
Class: BackedObservableList
public class BackedObservableList<T> implements List<T> {
private final List<T> backed;
public BackedObservableList() {
backed = new ArrayList();
}
public BackedObservableList(List<T> backed) {
this.backed = backed;
}
/*
You will want to override every method. For any method that performs an add/remove
operation, you will have to do some coding / testing. I'll do an add() op, a remove()
op, and an interator in this example. Anything that is not an add/remove op, you can straight up delegate it to the underlying list.
Also remember that list.clear() is a removal operation, where you can simply iterate through the backed list and call the overide remove(T t) method, or just plop the whole backed list into the ListChangeEvent<T> class and delegate to the backed array again.
*/
#Override
public boolean add(T e) {
if (backed.add(e)) {
ListChangeEvent<T> event = new ListChangeEvent(this, backed.indexOf(e), backed.indexOf(e) + 1, true, e);
notifyListeners(event);
return true;
}
return false;
}
}
#Override
public boolean remove(Object o) {
if (backed.remove(o)) {
ListChangeEvent<T> event = new ListChangeEvent(this, backed.indexOf(o),
backed.indexOf(o) + 1, false, o);
notifyListeners(event);
return true;
}
return false;
}
/*
The iterator seemed easy enough, until I remembered the iterator.remove() call.
I still haven't fully tested it (it works, but only as far as I've used it)
*/
#Override
public Iterator<T> iterator() {
return new Iterator<T>() {
T currentItem = null;
int currentIndex = 0;
#Override
public boolean hasNext() {
return backed.size() > currentIndex;
}
#Override
public T next() {
return currentItem = backed.get(currentIndex++);
}
#Override
public void remove() {
if (backed.remove(currentItem)) {
currentIndex--;
notifyListeners(new ListChangeEvent<T>(backed, currentIndex, currentIndex + 1, false, currentItem));
}
}
};
}
private void notifyListeners(ListChangeEvent<T> event) {
for (BackedListListener<T> listener : listeners) {
listener.setOnChanged(event);
}
}
private final List<BackedListListener> listeners = new ArrayList();
public void addListener(BackedListListener<T> listener) {
listeners.add(listener);
}
Class: ListChangeEvent
It simply provides a reference to the backed list (which you may want to wrap with Collections.unmodifiableList()
public class ListChangeEvent<T> {
private final List<T> source;
private final List<T> changeList;
private final boolean wasAdded;
private final int to, from;
public ListChangeEvent(List<T> source, int from, int to, boolean wasAdded, T... changeItems) {
this(source, from, to, wasAdded, Arrays.asList(changeItems));
}
public ListChangeEvent(List<T> source, int from, int to, boolean wasAdded, List<T> changeItems) {
this.source = source;
this.changeList = changeItems;
this.wasAdded = wasAdded;
this.to = to;
this.from = from;
}
public int getFrom() {
return from;
}
public int getTo() {
return to;
}
public List<T> getSource() {
return source;
}
public List<T> getChangeList() {
return changeList;
}
public boolean wasAdded() {
return wasAdded;
}
public boolean wasRemoved() {
return !wasAdded;
}
}
Class: BackedListListener
/*
Finally a little functional interface... or, because I was too lazy to change it to one, a simple one-liner abstract class with some generics
*/
public abstract class BackedListListener<T> {
public abstract void setOnChanged(ListChangeEvent<T> event);
}
the resp. ;)
private class MyList extends ArrayList<Objects> {
#Override
public void sort(Comparator c) {
super.sort(c);
resetLancamentos(); // call some metod ;)
}
//...
#Override
public boolean removeAll(Collection c) {
//To change body of generated methods, choose Tools | Templates.
boolean ret = super.removeAll(c);
resetLancamentos(); // some metod like fireObjChanged() will do the job too
return ret;
}
}
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?