Understanding the code flow: diamond operator and anonymous class - java

I learned that from Java 9 it's possible to use the diamond operator while creating an anonymous class only if the type argument is inferable
After that, I don't understand this code, it's from Java Generic Programming theory
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Main {
public static <T> Iterable<T> getIterable(T... elems) {
return new Iterable<T>() {
#Override
public Iterator<T> iterator() {
return new Iterator<>() {
int i = 0;
#Override
public boolean hasNext() {
return i < elems.length;
}
#Override
public T next() {
if(!hasNext()) throw new NoSuchElementException();
return elems[i++];
}
};
}
};
}
public static void main(String[] args) throws Exception{
String[] path = {"UP", "DOWN", "LEFT", "RIGHT"};
Iterable<String> ipaths = getIterable(path);
for (String apath : ipaths) {
System.out.println(apath);
}
}
}
I don't understand how this code work, I tried with debugger but it's still really strange to me, the first "return new Iterator()" in my IntellijIDEA is in grey, seems like it's treated like a comment
My knowledge about anonymous class is just a simple creation like that
Example ex = new Example() {
//fields
// no constructor
//method, overriden method from the superclass
};

Related

Cannot infer type arguments for Generic Class

I am trying to create Expression Tree using the Postfix Expression.
This needs a Stack which could hold Tree Objects.
I created a generic Stack class which could except <TreeTemp> as type argument.
On trying to initialize the stack with following statement, its giving "Cannot infer type arguments for TreeStack<>" error.
private TreeStack<TreeTemp> stack1 = new TreeStack<>(new TreeTemp());
Stack Class:
public class TreeStack<T> {
private T [] stackElem;
private final int MAXSTACKSIZE;
private int top;
public TreeStack(Class<T> t) {
top = -1;
MAXSTACKSIZE = 20;
final T[] stackElem = (T[]) Array.newInstance(t, MAXSTACKSIZE);
this.stackElem = stackElem;
}
public void push(T elem) throws Exception{
if(isFull()) {
stackElem[++top] = elem;
}
else
throw new Exception("Stack is already Full");
}
public T pop() throws Exception {
if(isEmpty()) {
return stackElem[top--];
}
else
throw new Exception("Stack is Empty");
}
public boolean isEmpty() {return top == -1;}
public boolean isFull() {return top==MAXSTACKSIZE-1;}
}
Postfix.class(Class having method for creating tree)
public class PostFix {
private String expression = new String("A*B+C");
private char [] expElem = expression.toCharArray();
/*Error on below Statement*/
private TreeStack<TreeTemp> stack1 = new TreeStack<>(new TreeTemp());
public TreeTemp makeTree() throws Throwable {
try {
for(int i=0;i<expElem.length;i++) {
ExpNode eNode = new ExpNode();
eNode.setiData(expElem[i]);
TreeTemp t = new TreeTemp();
t.setRoot(eNode);
if(!Character.isLetter(expElem[i])) {
t.setLeftTree(stack1.pop());
t.setRightTree(stack1.pop());
}
stack1.push(t);
}
return stack1.pop();
}catch (Exception e) {
throw new Exception("Stack Error while creating a Tree", e);
}
}
public static void main(String[] args) throws Throwable {
PostFix pf = new PostFix();
TreeTemp t = pf.makeTree();
}
Tree Class(Type which i want to add into Stack):
public class TreeTemp {
private ExpNode root;
private TreeTemp leftTree;
private TreeTemp rightTree;
/*public TreeTemp(ExpNode expNode) {
root = expNode;
}*/
public TreeTemp getLeftTree() {
return leftTree;
}
public void setLeftTree(TreeTemp leftTree) {
this.leftTree = leftTree;
}
public TreeTemp getRightTree() {
return rightTree;
}
public void setRightTree(TreeTemp rightTree) {
this.rightTree = rightTree;
}
public ExpNode getRoot() {
return root;
}
public void setRoot(ExpNode node) {
this.root = node;
}
}
Can someone pls give some pointers.
Your TreeStack has only one constructor. Here it is:
public TreeStack(Class<T> t) {
Thus, to invoke it, you need to pass the class object that represents the class associated with the T type. So, the class itself, not 'some particular instance of T'. When you call it on your error line:
private TreeStack<TreeTemp> stack1 = new TreeStack<>(new TreeTemp());
You are passing an instance of TreeTemp. Not the concept 'TreeTemp, the class'. Try new TreeStack<>(TreeTemp.class);
Note that as a general rule, passing a Class<T> is a code smell; you're trying to make generics something that it isn't (you're trying to runtime reify). This is objectively bad: It means you can't make a TreeStack<List<String>>, for example, because you're restricted to the overlap where both generics as well as j.l.Class instances can represent the thing, and that's just simple, non-genericsed, non-primitive classes.
final T[] stackElem = (T[]) Array.newInstance(t, MAXSTACKSIZE);
Looks like the only reason you want that class is to make sure your array is properly typed.
This is not neccessary. Just make a new Object[] array, and cast to T anytime you need to return a T. Now your TreeStack constructor needs no arguments at all.
Check the source of java.util.ArrayList, which agrees with this assessment; it is backed by an Object array, not a T[].
The TreeStack constructor accepts a Class<T>, not a T, so you should do:
new TreeStack<>(TreeTemp.class);
Since this is an exercise to create expression trees, you don't really need to implement stacks from scratch. You should just use the ArrayDeque class through the Deque interface in the Java Collections API.
private Deque<TreeTemp> stack1 = new ArrayDeque<>();
Deque has all the methods your TreeStack has, and many more.

Iterator of iterable object should return the iterable object itself in Java

Suppose you have given a class in Java that extends the Iterable interface. This class has to provide an Iterator that should return the instance of the surrounding class, take a look at the main method.
public class Test implements Iterable<Test> {
#Override
public Iterator<Test> iterator() {
return new Iterator<Test>() {
private boolean onlyOnce = false;
#Override
public boolean hasNext() {
return false;
}
#Override
public Test next() {
if (!onlyOnce) {
onlyOnce = true;
// TODO return
}
throw new NoSuchElementException("Iterator has already been called");
}
};
}
public static void main(String[] args) {
Test test = new Test();
Test test2 = test.iterator().next();
boolean b = test == test2; // should be true
}
}
How could this issue be solved in Java?
In order to return the enclosing instance of Test, use a qualified this:
return Test.this;
However, a much neater way to implement the method would be to use an existing iterator implementation:
#Override
public Iterator<Test> iterator() {
return Arrays.asList(this).iterator();
// or Collections.singleton(this).iterator()
// or Stream.of(this).iterator()
// or many other possibilities.
}

Java-like code (maps, function pointers)

I need to do something similar to the following code:
#include <iostream>
#include <map>
using namespace std;
typedef char (*intfunction)() ;
char a(){
return 'a';
}
char b(){
return 'b';
}
int main() {
map<char, intfunction> mapita;
mapita['a'] = &a;
mapita['b'] = &b;
cout << mapita['a']()
<< mapita['b']();
return 0;
}
As a matter of fact, I don't really have to much knowledge in Java, so I'm searching for some help with this.
Is there any possible way to simulate or do the same as the code above? I was seeing some examples with interfaces and so on, but couldn't make it work the same way.
Check out this code:
import java.util.HashMap;
import java.util.Map;
public class test2 {
interface Test {
public String method();
}
public static void main(final String[] arg) {
final Map<String, Test> map = new HashMap<String, Test>();
map.put("a", new Test() {
#Override
public String method() {
return "aaa";
}
});
map.put("b", new Test() {
#Override
public String method() {
return "bbb";
}
});
System.out.println(map.get("a").method());
System.out.println(map.get("b").method());
}
}
I would like to use OOP solution to implement the behavior you want.
IDEA
As your code illustrates that you want to call different method accorrding to different key.
This scene perfectly matches the Factory Design Pattern, So i create a factory returning the method instance based on the key passed in. Then i abstract the function to a interface BaseMethod. Then, you can create classes implementing the interface to achieve the same method signature when your business growing.
Need to be improve
the factory is not thread safe.
the interface, classes need to be in multiple files.
Code
import java.util.HashMap;
import java.util.Map;
interface BaseMethod {
public void run();
}
class HelloWoldMethod implements BaseMethod {
public void run() {
System.out.println("Hello world");
}
}
class MethodFactory {
private static MethodFactory ins = null;
private final static Map<String, BaseMethod> map = new HashMap<String, BaseMethod>();
private MethodFactory() {
map.put("hello", new HelloWoldMethod());
}
public static BaseMethod getMethod(String key) {
if (null == ins) {
ins = new MethodFactory();
}
return map.get(key);
}
}
public class Test {
public static void main(String [] args) {
BaseMethod ins = MethodFactory.getMethod("hello");
if (null != ins) {
ins.run();
} else {
System.out.println("no method found");
}
}
}
The only real potential solution I can think of would be a map of runnable objects:
public void doSomething() {...}
//elsewheres
Map<String, Runnable> map = new HashMap<>();
//Java 7
map.put("test", new Runnable() { doSomething(); });
//Java 8
map.put("test", () -> { doSomething(); });
Either that, or a class that implements a common interface for your object (if you need some returned value).
the syntax might be a bit off, but
import java.utils.HashMap;
class CharHolder {
private char myChar;
CharHolder( char someChar ) {
myChar = someChar;
}
char getChar() {
return myChar;
}
public static void main(String[] args) {
HashMap<Character, CharHolder> mapita = new HashMap<>();
mapita.put( 'a', new CharHolder('a') );
mapita.put( 'b', new CharHolder('b') );
System.out.println( mapita.get('a').getChar() + " " + mapita.get('b').getChar() );
}
}
the output should be:
a b

Interview: Collections Iterator

Hi guys i got this as an interview question and was having trouble with it. I am familiar with generics/collections & iterator but the manner i which the Collection is declared completely threw me.
Heres the question: Contained in the provided workspace is cocI, the start of a class that implements an Iterator that can be used to iterate a Collection of Collections. The Collection of Collections is passed into the constructor of the class. The Iterator should iterate through the contents depth-first.
For example, if the Collection of Collections looks like the following:
[0] – [“A”, “B”, “C”]
[1] – [“D”]
[2] – [“E”, “F”]
The iterator should then return the contents in the following order: “A”, “B”, “C”, “D”, “E”, “F”
Q.Provide implementations for the hasNext() and next() methods in cocI
Thanks
import java.util.Collection;
import java.util.Iterator;
public class cocI implements Iterator<Object> {
private Collection<Collection<Object>> _collOfColl = null;
public cocI(Collection<Collection<Object>> collofColl) {
_collOfColl = collofColl;
}
public boolean hasNext() {
// TODO implement this method
return false;
}
public Object next() {
// TODO implement this method
return null;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
All you need to do is keep track of the current collection's iterator within the collection of collections. The hasnext() method, which is the tricky part, will then do one of two things: return true if the current iterator has more elements, if not search until we find a collection that has elements. If we exhaust all the collections, return false.
public class Cocl implements Iterator<Object> {
private Collection<Collection<Object>> _collOfColl = null;
private final Iterator<Collection<Object>> coClIterator;
private Iterator<Object> currentColIterator;
public Cocl(Collection<Collection<Object>> collofColl) {
_collOfColl = collofColl;
coClIterator = collofColl.iterator();
if (coClIterator.hasNext()) {
currentColIterator = coClIterator.next().iterator();
}
}
public boolean hasNext() {
if (currentColIterator == null) {
return false;
}
if (!currentColIterator.hasNext()) {
while (coClIterator.hasNext()) {
currentColIterator = coClIterator.next().iterator();
if (currentColIterator.hasNext()) {
return true;
}
}
return false;
} else {
return true;
}
}
public Object next() {
if (hasNext()) {
return currentColIterator.next();
}
throw new NoSuchElementException();
}
public void remove() {
throw new UnsupportedOperationException();
}
public static void main(String[] args) {
Collection<Object> one = Arrays.asList((Object) "A", (Object) "B", (Object) "C");
Collection<Object> two = Arrays.asList((Object) "D", (Object) "E");
Cocl cocl = new Cocl(Arrays.asList(one, two));
while (cocl.hasNext()) {
Object a = cocl.next();
System.out.println(a);
}
}
}
A couple of introductory remarks:
cocI is an odd class name; it should start with a capital letter.
The interface you are supposed to implement doesn't use generics effectively. You should be able to use a data type more specific than Object.
It is good practice to use the #Override annotation.
The solution involves an iterator for the outer collection and an iterator for the inner collection. When the inner iterator runs out of elements, it needs to be replaced with an iterator for the next collection. However, considering that a collection could be empty, the advancement needs to be done in a loop, which I've put in an advanceCollection() helper.
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class cocI<T> implements Iterator<T> {
private Iterator<Collection<T>> outerIterator;
private Iterator<T> innerIterator;
public cocI(Collection<Collection<T>> collofColl) {
this.outerIterator = collofColl.iterator();
advanceCollection();
}
#Override
public boolean hasNext() {
return this.innerIterator != null && this.innerIterator.hasNext();
}
#Override
public T next() {
if (this.innerIterator == null) {
throw new NoSuchElementException();
}
try {
return this.innerIterator.next();
} finally {
advanceCollection();
}
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
private void advanceCollection() {
while ((this.innerIterator == null || !this.innerIterator.hasNext())
&& this.outerIterator.hasNext()) {
this.innerIterator = this.outerIterator.next().iterator();
}
}
}
There is one slightly tricky piece of code I used:
try {
return this.innerIterator.next();
} finally {
advanceCollection();
}
It is roughly equivalent to:
T result = this.innerIterator.next();
advanceCollection();
return result;

Converting an Enumeration to Iterator

I have a problem on a worksheet which is to create an adapter to convert an Enumeration to an Iterator. When I try to run the following code I get a null pointer exception.
import java.util.Vector;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Iterator;
public class ConvertEnumeration {
public static void main(String [] args) {
int [] ourArray = {0,1,2,3,4,5,6,7,8,9};
Vector vector = new Vector(Arrays.asList(ourArray));
//Get Enumerator
Enumeration enumerator = vector.elements();
EnumerationToIterator enumToIt = new EnumerationToIterator(enumerator);
while(enumToIt.hasNext()) {
System.out.println(enumToIt.next());
}
}
}
//Convert our enumeration to Iterator!
class EnumerationToIterator implements Iterator {
//Our enumeration
Enumeration enmueration;
//Constructor
public EnumerationToIterator(Enumeration enmueration){
enmueration = this.enmueration;
}
//Our Methods
public boolean hasNext(){
return enmueration.hasMoreElements();
}
public Object next(){
return enmueration.nextElement();
}
public void remove(){
throw new UnsupportedOperationException();
}
}
Another point to note is that I can not print out the int's from the Enumeration after I have created it in the first place.
Java 5 and Later
No need to reinvent the wheel. Just use Collections.list(Enumeration<T> e), which returns an ArrayList<T>. Then use ArrayList.iterator() to get an Iterator.
Java 9 and Later
Enumerations now have a method to convert directly to an iterator:
enumeration.asIterator();
Java 9 offers a new default method: Iterator<E> asIterator()
Wrong assignment in your constructor. It needs to be this.enmueration = enmueration;
enmueration is the constructor argument, and this.enmueration is the object attribute.
public class ConvertEnumeration {
public static void main(String [] args) {
// int [] ourArray = {0,1,2,3,4,5,6,7,8,9};
Vector<Integer> vector = new Vector<Integer>(Arrays.asList(0,1,2,3,4,5,6,7,8,9));
//Get Enumerator
Enumeration<Integer> enumerator = vector.elements();
EnumerationToIterator<Integer> enumToIt = new EnumerationToIterator<Integer>(enumerator);
while(enumToIt.hasNext()) {
System.out.println(enumToIt.next());
}
}
}
//Convert our enumeration to Iterator!
class EnumerationToIterator<T> implements Iterator<T> {
//Our enumeration
Enumeration<T> enmueration;
//Constructor
public EnumerationToIterator(Enumeration<T> enmueration){
this.enmueration = enmueration;
}
//Our Methods
public boolean hasNext(){
return enmueration.hasMoreElements();
}
public T next(){
return enmueration.nextElement();
}
public void remove(){
throw new UnsupportedOperationException();
}
}

Categories