Implementing Iterable in Java - java

I have the following code
public class A extends Iterable<Integer> {
...
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
A a;
public boolean hasNext() {
...
}
public Integer next() {
...
}
public void remove(){
...
}
};
I would like to initialize the "a" field in the anonymous class with the instance of A that iterator method was called on. Is it possible?
Thank you.

You don't need to.
You can call methods on the outer class normally within the inner class.
When you compile it, the compiler will automatically generate a hidden field that contains a reference to the outer class.
To reference this variable yourself, you can write A.this. (A.this is the compiler-generated field and is equivalent to your a field)

Try this:
public class A extends Iterable<Integer> {
public Iterator<Integer> iterator() {
final A a = this;
return new Iterator<Integer>() {
public boolean hasNext() {
// here you can use 'a'
}
}
}
}

Use :
A a = A.this

Related

Is there a way we can hide a particular method only for some classes IN the package? [duplicate]

Here's an example:
class A
{
List l = new List ();
list.insert("x");
}
class List
{
...
public void insert ()
{
/*insertion occurs*/
}
...
}
Is it possible at all to keep the insert() method public, but limit access only to class A so that no other class can access it, only when called from A?
I would pass the object that is calling the method as an argument, i.e.
list.insert("x", this);
And then check if the passed Object is an Instance of Class A
public void insert (String x, Object o)
{
if(o instanceof ClassA){
/*insertion occurs*/
}
}
If the method is public, everyone can access it. The trick to access control like yours is to expose a set of public operations through an interface, add auxiliary operations to a private class implementing the interface, and make your users program to the interface, not to a class.
Here is an example:
public interface MyList {
Object elementAt(int i);
}
public class A {
private static class MyListImpl implements MyList {
public Object elementAt(int i) {
...
}
public void insert(Object element) {
...
}
}
private final MyListImpl list = new MyListImpl();
public MyList getList() { return list; }
public void insert(Object o) { list.insert(o); }
}
Usage scenario:
A a = new A();
a.insert(123);
a.insert("quick brown fox");
MyList lst = a.getList();
System.out.println(lst.elementAt(0));
System.out.println(lst.elementAt(1));
Yes, you can pass calling object as an argument and put a check in insert() method before actual code.
public void insert(Object obj){
if(obj instanceof A){
//your code block
}
}
Please note that this will allow all the classes that extends A as well to call insert. If you want to restrict only for class A, add additional check.
public void insert(Object obj){
if((obj instanceof A) && obj.getClass().getSimpleName().equals("A")){
//your code block
}
}
we can also achieve second case with only condition "obj.getClass().getSimpleName().equals("A")" as well.
The best you can do using access modifiers is to make the method package private (remove the public keyword) and keep only those two classes in the same package.
If all the "inner classes" stuff in the previous answers confuses you, there is another way that may be more intuitive (assuming you've learned about the extends keyword and inheritance). You can simply make the insert() method protected instead of public and make class A extend List. For example:
public class List {
...
protected void insert() {
//insertion occurs
}
...
}
public class A extends List {
...
}
As long as no other classes extend List, only objects of types A and List will ever be able to use the insert() method.
package problems;
public class Problem1 {
public static void main(String[] args) {
B b = new B();
b.methodInB();
C c = new C();
c.methodNotInB();
}
}
class A {
public void onlyB() {
StackTraceElement[] stackTraceElements = Thread.currentThread()
.getStackTrace();
if (!problems.B.class.getCanonicalName().equals(
stackTraceElements[stackTraceElements.length - 2]
.getClassName())) {
System.err.println("You are not authorized to call me!!");
return;
}
System.out.println("You are authorized to call me!!");
}
}
class B {
public void methodInB() {
A a = new A();
a.onlyB();
}
}
class C {
public void methodNotInB() {
A a = new A();
a.onlyB();
}
}
Put it as inner class in A or you can do another thing ...
Let insert takes one parameter with type of Object and in the beginning of it check if the parameter's type is A .... and when you call it send the calling object...
maby its not a good idea but it will do what you want
Put it into the permitted class and make it private.

returning inner-class object from interface

/**
* Created by unibodydesignn on 11.03.2017.
*/
public interface Enumeration
{
// Returns true if another element in the collection exists
public boolean hasNext();
// Returns the next element in the collection as an Object
public Object getNext(); }
/**
* NameCollection implements a collection of names using
* a simple array.
*/
public class NameCollection
{
String[] names;
//this array will be initiliazed at outside
NameCollection(String[] names)
{
this.names = names;
}
/**
* getEnumeration should return an instance of a class that
implements
* the Enumeration interface where hasNext() and getNext()
* correspond to data stored within the names array.
*/
Enumeration getEnumeration ()
{
}
public boolean hasNext()
{
//i will define this method here
}
public Object getNext()
{
//i will define getNext() here
}
Complete the method getEnumeration() so that it returns an anonymous inner class that corresponds to the Enumeration interface for the names array in
NamesCollection. Then write a main method that creates a NamesCollection
object with a sample array of strings, retrieves the Enumeration for this class via
getEnumeration(), and then iterates through the enumeration outputting each
name using the getNext() method.
I don't understand this question's concept. I clearly do not know what to do or where to start? Can I find Java's default hasNext() definition?
It is not homework.
It is a programming project from Absolute Java book. Chapter 13. P3.
Complete the method getEnumeration() so that it returns an anonymous inner class that corresponds to the Enumeration interface for the names array in NamesCollection.
The purpose of the exercise seems to be working with anonymous classes.
For example, instead of creating a named class like this:
class NamesEnumeration implements Enumeration {
#Override
public boolean hasNext() {
// ...
}
#Override
public Object getNext() {
// ...
}
}
... the instructions guide you to use an anonymous class instead, like this:
Enumeration getEnumeration() {
return new Enumeration() {
#Override
public boolean hasNext() {
// ...
}
#Override
public Object getNext() {
// ...
}
};
}
An important point is that anonymous implementation can use variables visible in its scope. Most notably for this example,
the names field of the enclosing NamesCollection class.
In the NamesCollection class,
you don't need the hasNext and getNext methods.
So the class should look something like this:
public class NameCollection {
final String[] names;
NameCollection(String[] names) {
this.names = names.clone();
}
Enumeration getEnumeration() {
return new Enumeration() {
int currentIndex = 0;
// ^^^^^^^^^^^^ this is a hint for you
#Override
public boolean hasNext() {
// ...
}
#Override
public Object getNext() {
// ...
}
};
}
}
I've made some minor improvements, and added a hint to help you complete the implementation.
Lastly, the exercise also asks to add a main method to exercise this class. That should be something like this:
public static void main(String[] args) {
String[] sample = {"hello", "world"};
NameCollection namesCollection = new NameCollection(sample);
Enumeration names = namesCollection.getEnumeration();
while (names.hasNext()) {
System.out.println(names.getNext());
}
}
i dont know about that book you say, but lets understand what is requested:
What you need to do is create an implementation of the Enumeration Interface, i dont know if this chapter is about Interfaces, or Enumarations.
1: "Complete the method getEnumeration() so that it returns an anonymous inner class that corresponds to the Enumeration interface for the names array in NamesCollection".
Here you need to return an implementation of the Enumeration interface, the question says to create an Anonymous class (but i sugest to create an Inner Class, maybe Private Inner Class). like this, inside the NameCollection class:
public Enumeration getEnumeration(){
Enumeration enumerat = new Enumeration(){
private int index = 0;
public boolean hasNext(){
return names.length > index;
}
public Object getNext(){
return names[index++];
}
};
return enumerat;
}
The method returns an implementation of the Enumeration class that you can use to traverse throught the array of names you passed to the constructor of the NameCollection class.
2: "Then write a main method that creates a NamesCollection object with a sample array of strings, retrieves the Enumeration for this class via getEnumeration(), and then iterates through the enumeration outputting each name using the getNext() method".
Here you just need to create a test class for your implementation:
public class Main {
public static void main(String[] args) {
NameCollection nc = new NameCollection(new String[]{ "Adriane", "Beatriz" });
Enumeration en = nc.getEnumeration();
while( en.hasNext() ){
System.out.printf("Name: %s \n", en.getNext() );
}
}
}

How to make `this` point to the outer class where the inner class has the same method name

Let's say I have the following code:
abstract class MyStream
{
public abstract Iterable<Integer> getIterable();
public MyStream append(final int i)
{
return new MyStream()
{
#Override
public Iterable<Integer> getIterable()
{
return cons(/*outer class's*/getIterable(), i);
}
};
}
public static Iterable<Integer> cons(Iterable<Integer> iter, int i) { /* implementation */ }
}
How can I reference getIterable of the outer class from the inner class with the same name?
MyStream.this should point to the inner class here, right? How to show an outer class with the same name?
If you call MyStream.this from the anonymous class it will point to the outer class so the code below should work as you expect:
return const(MyStream.this.getIterable(), i);
(if it did not you would get a StackOverflowError).
The reason why it works is that an anonymous class is an inner class.
Simplified example that prints outer 1:
public static void main(String args[]) {
MyClass c = new MyClass() {
#Override public String get() { return "outer"; }
};
System.out.println(c.append(1).get());
}
static abstract class MyClass {
public abstract String get();
public MyClass append(final int i) {
return new MyClass() {
#Override public String get() {
return cons(MyClass.this.get(), i);
}
};
}
public static String cons(String iter, int i) { return iter + " " + i; }
}
MyStream.this does not point to the inner class. The inner class is anonymous. It may confuse you because you used new MyStream() {...}, but in fact it's a new inner class, which has an internal name, and the new MyStream() {...} syntax simply serves to replace the SomeClass extends MyStream syntax.
It is worth noting that the inner class both extends MyClass and is nested in it. This means that both super and MyClass.this exist and are MyClass references, but they are two distinct object instances. super points to the inner class instance itself, but looks at it as if it was MyClass, while MyClass.this is the enclosing object.

Java: How to limit access of a method to a specific class?

Here's an example:
class A
{
List l = new List ();
list.insert("x");
}
class List
{
...
public void insert ()
{
/*insertion occurs*/
}
...
}
Is it possible at all to keep the insert() method public, but limit access only to class A so that no other class can access it, only when called from A?
I would pass the object that is calling the method as an argument, i.e.
list.insert("x", this);
And then check if the passed Object is an Instance of Class A
public void insert (String x, Object o)
{
if(o instanceof ClassA){
/*insertion occurs*/
}
}
If the method is public, everyone can access it. The trick to access control like yours is to expose a set of public operations through an interface, add auxiliary operations to a private class implementing the interface, and make your users program to the interface, not to a class.
Here is an example:
public interface MyList {
Object elementAt(int i);
}
public class A {
private static class MyListImpl implements MyList {
public Object elementAt(int i) {
...
}
public void insert(Object element) {
...
}
}
private final MyListImpl list = new MyListImpl();
public MyList getList() { return list; }
public void insert(Object o) { list.insert(o); }
}
Usage scenario:
A a = new A();
a.insert(123);
a.insert("quick brown fox");
MyList lst = a.getList();
System.out.println(lst.elementAt(0));
System.out.println(lst.elementAt(1));
Yes, you can pass calling object as an argument and put a check in insert() method before actual code.
public void insert(Object obj){
if(obj instanceof A){
//your code block
}
}
Please note that this will allow all the classes that extends A as well to call insert. If you want to restrict only for class A, add additional check.
public void insert(Object obj){
if((obj instanceof A) && obj.getClass().getSimpleName().equals("A")){
//your code block
}
}
we can also achieve second case with only condition "obj.getClass().getSimpleName().equals("A")" as well.
The best you can do using access modifiers is to make the method package private (remove the public keyword) and keep only those two classes in the same package.
If all the "inner classes" stuff in the previous answers confuses you, there is another way that may be more intuitive (assuming you've learned about the extends keyword and inheritance). You can simply make the insert() method protected instead of public and make class A extend List. For example:
public class List {
...
protected void insert() {
//insertion occurs
}
...
}
public class A extends List {
...
}
As long as no other classes extend List, only objects of types A and List will ever be able to use the insert() method.
package problems;
public class Problem1 {
public static void main(String[] args) {
B b = new B();
b.methodInB();
C c = new C();
c.methodNotInB();
}
}
class A {
public void onlyB() {
StackTraceElement[] stackTraceElements = Thread.currentThread()
.getStackTrace();
if (!problems.B.class.getCanonicalName().equals(
stackTraceElements[stackTraceElements.length - 2]
.getClassName())) {
System.err.println("You are not authorized to call me!!");
return;
}
System.out.println("You are authorized to call me!!");
}
}
class B {
public void methodInB() {
A a = new A();
a.onlyB();
}
}
class C {
public void methodNotInB() {
A a = new A();
a.onlyB();
}
}
Put it as inner class in A or you can do another thing ...
Let insert takes one parameter with type of Object and in the beginning of it check if the parameter's type is A .... and when you call it send the calling object...
maby its not a good idea but it will do what you want
Put it into the permitted class and make it private.

What does the syntax mean in Java: new Stream<Integer>(){ ... }?

I have encountered the following Java syntax that I don't recognize.
This part is fine:
public abstract class Stream<T> implements Iterator<T> {
public boolean hasNext() {
return true; }
public void remove() {
throw new RuntimeException("Unsupported Operation"); }
}
But this I don't get:
Stream<Integer> ones = new Stream<Integer>() {
public Integer next() {
return 1; }
};
while(true){
System.out.print(ones.next() + ", ");
}
What it is?
This is providing an inline (anonymous) subclass of the Stream class.
Functionally, it is the same as:
public NewClass extends Stream {
public Integer next() {
return 1;
}
}
and
void someMethodInAnotherClass {
Stream stream = new NewClass();
}
but as this class definition isn't used outside the method body, you can define it as anonymous.
ones = new Stream<Integer>() {
public Integer next() {
return 1; }
};
Assigns a new instance of an anonymous implementation of Stream<Integer> (that contains a virtually unlimited number of 1s. You may find more on anonymous classes in Java In A Nutshell
This is defining a Anonymous class which implements the Stream interface. To implement the interface we need to implement the method next.

Categories