How to refer to Enclosing class from Inner class? - java

I am extending ArrayList to create a custom ArrayList that can be modified using normal ArrayList methods while iterating over it. For this I am also creating an Iterator.
public class SynchronizedList<E> extends ArrayList<E>
{
// Fields here
//Constructors and methods here
public class SynchronizedListIterator<E> implements Iterator<E>
{
public int index;
private E current;
public boolean hasNext()
{
synchronized (/* reference to enclosing List object */) {
//code goes here
}
return false;
}
//more methods here
}
}
During my hasNext() and next() methods, I need to make sure the list is not modified (it can be modified at any other time). Hence I need to refer to my enclosing type in my synchronized() block.

EnclosingType.this. So in your case, it would be SynchronizedList.this.

Related

Interface methods in a class that does not implement it?

public interface Iterator<T> {
// Returns true if the iterator is valid (points to an element), false otherwise.
boolean isValid();
// Returns the current element and moves forward. This method can only be called if the iterator is valid. If the iterator points to the last element, it becomes invalid after the call.
T next();
// Returns the current element and moves backwards. This method can only be called if the iterator is valid. If the iterator points to the first element, it becomes invalid after the call.
T prev();
}
In a class that does not implement interface Iterator, how is it possible to create a method that returns Iterator<K>, when you can only create methods for an interface inside a class that implements it?
public class ABC<K> implements EFG<K>{
public Iterator<K> minIt() {
//method body
//return Iterator<K> variable
}
}
The class ABC containing the method minIt() does not implement Iterator<T>
(No classes implement the interface Iterator <T> )
You can use an Anonymous Class that implements the interface:
For instance:
interface Foo<T> {
T foo();
}
class Bar<T> {
T t;
public Foo<T> bar() {
return new Foo<T>() { // <-- Anonymous class implementing `Foo`
public T foo() {
return t;
}
};
}
}
Execution:
Bar<String> b = new Bar<>();
b.t = "hello"; // with a setter in real life
Foo<String> f = b.bar();
f.foo(); // will return "hello"
The other option which I think would be the most common is to use a method that returns the interface, for instance the list interface has an iterator() method even though it itself doesn't implements the Iterator interface.
List<String> list = new ArrayList<>();
Iterator<String> stringIterator = list.iterator();
Here's the implementation
Simple. By making a class that implements it. Note that you have a type that you came up with on your own and you named it Iterator. Given that java.util.Iterator exists, this is a really bad idea. You should pick another name.
public class ABC<K> implements EFG<K> {
// Let's say this contains the items that can be iterated over.
private List<K> list = new ArrayList<K>();
class MyIterator implements my.pkg.Iterator<K> {
private int position = 0;
#Override public boolean isValid() {
return position > -1 && position < list.size();
}
#Override public K next() {
if (!isValid()) throw new NoSuchElementException();
return list.get(position++);
}
#Override public K prev() {
if (!isValid()) throw new NoSuchElementException();
return list.get(position--);
}
}
public Iterator<K> minIt() {
return new MyIterator<K>();
}
}
Note that classes that you put in classes can only be constructed in instance contexts within that class: They have a 'secret' field of your outer's type. Hence why the code in MyIterator can access the list field of your outer class.
Java has 'anonymous inner class literal' syntax which lets you shorten this: Instead of explicitly declaring class MyIterator, you can also write:
public Iterator<K> minIt() {
return new your.pkg.Iterator<K>() {
private int position = 0;
#Override public boolean isValid() {
// same code goes here as the previous snippet
}
};
}
This anonymous inner class form is a lot more common. It's just syntax sugar - a shorter way to write the same thing.

Create a Class That extends Java.util.ArrayList

I am trying to create class that extends the java.util.ArrayList by overriding
the add method in the following way: it does nothing if the object to be added already exists
in the collection; otherwise it calls the add method in the super class to add the object into
the collection.
My code look like that so far but it gives a NullPointerException:
import java.util.ArrayList;
public class myArrayList<E> extends ArrayList<E> {
public ArrayList<E> mylist;
#Override
public boolean add(E e) {
if (!mylist.contains(e)) {
super.add(e);
return true;
} else {
return false;
}
}
}
public static void main(String[] args) {
myArrayList<Integer> listing = new myArrayList<Integer>();
listing.add(4);
listing.add(4);
for (int i = 0; i < listing.size(); i++) {
System.out.println(listing.get(i));
}
}
While we can't be sure this is your problem (unless you show us the stacktrace!), it looks like an NPE is likely to occur in this line:
if (!mylist.contains(e)) {
because mylist is never initialized.
In fact, if you are trying to extend ArrayList rather than create a list wrapper, the mylist variable should not exist at all. The list state is in the superclasses private variables. Instead, the add method should probably be written like this:
#Override
public boolean add(E e) {
if (!super.contains(e)) {
return super.add(e); // See note
} else {
return false;
}
}
Note: in general, you should return whatever the superclass returns here. However, when the superclass is ArrayList, we know1 that add will return true, so this is only "saving" a line of code. There might be marginal performance difference, depending on how smart the JIT optimizer is.
1 - We know because the ArrayList.add javadoc specifically states that true is returned.
But this looks like you are trying to create a "set-like" list class. There could be better alternatives; e.g. LinkedHashSet has a defined iteration order, and addition is O(1) rather than O(N). (Admittedly, LinkedHashSet uses a lot more memory, and it has no efficient equivalent to the positional List.get(int) method.)
You got a NullPointerException on this line if (!mylist.contains(e)) { because myList is not instanciated in the default constructor.
public MyArrayList() {
this.myList = new ArrayList<>();
}
But.. you mix inheritance and composition here...
That means add will be applied to myList and get(index) will be applied on this.. So you actually maintain 2 lists here..
In you example myList.contains will always return false because you never add something into. this -> super.add(e) is the same than this.add(e) and it is a different instance of list.
So just removed myList instance field and replace your add like this :
#Override
public boolean add(E e) {
if (!contains(e)) {
add(e);
return true;
} else {
return false;
}
}
Watch out that this class is not thread-safe. Here there is a check-then-act race condition (check = contains(), act = add())
Finally List are designed to allow duplicates... if you don't want duplicates.. just use a Set

this keyword doesn't represent an object

Does anyone know why can we loop through the "this" keyword here (in the subsetOf method)? To my knowledge this represents a JAVA object. Some extensive explanations are welcomed, would like to know why "this" can work in this way.
public class ArrayListSet<E> implements Set<E> {
private ArrayList<E> elements;
public ArrayListSet() {
elements = new ArrayList<>();
}
#Override
public void add(E e) {
if (!elements.contains(e))
elements.add(e);
}
#Override
public void remove(E e) {
elements.remove(e);
}
#Override
public boolean contains(Object e) {
return elements.contains(e);
}
#Override
public int size() {
return elements.size();
}
#Override
public boolean subsetOf(Set<?> other) {
for (E e : this) {
if (!other.contains(e))
return false;
}
return true;
}
}
You are declaring a class which implements the Set interface which itself extends the Iterable through the Collection interface. Any Object which is an implementation of the Iterable interface can be used inside a for-each loop.
So the inheritance hierarchy is this for your class:
Iterable
^
|
Collection
^
|
Set
^
|
ArrayListSet
Also the this keyword always refers to the current instance. In your code when you execute the subsetOf() the this will point to an instance of ArrayListSet (which was used to invoke the subSetOf() method) which is a type of Iterable through inheritance, so you can use it in a for-each loop.
Also since you are implementing a Set you need to supply an implementation of the Iterator<E> iterator(); method defined in the Set interface to make it an Iterable.
As implementations of the Iterable interface requires a iterator() method which returns an instance of the Iterator object. The Iterator Object will be used by the for-each loop to iterate over the elements of the ArrayListSet.
The implementation of the Iterator type returned from the iterator() method actually defines the iteration logic used by the for-each loop.
To use any Object in a for-each loop:
Step 1: Extend Iterable directly or through other Iterable types.
Step 2: Provide implementation of the Iterator iterator() method inherited from the Iterable interface.
Step 3: Implement an Iterator and return its instance from the iterator() method.
You can iterate through this since it represents a set. The set is iterable. Therefore it is valid syntax.

Inheriting from implementation of LinkedList to a SortedLinkedList, access private Node

I am quite new to Java and I am trying to do my own implementation of a Linked List and then extend that to a Sorted Linked List.
I think my problem is that the SortedLinkedList class that inherits from LinkedList and > dont have access to the private Node start; in the LinkedList. This is a simplification of the code.
I start by creating my own Interface of the List class
interface List<T> {
public int size();
public void add(int pos, T x);
public void add(T x);
public T get(int pos);
public T remove();
}
And saves this as List.java and then I create my linked list class
class LinkedList<T> implements List<T> {
//Starting point of the Linked List
private Node start;
public class Node {
T x;
Node next;
public Node(T x) {
this.x= x;
}
public T getValue(){
return x;
}
}
//Here is implementations of all the methods from List<T> and some ohers
}
This all works as expected, and I have tested all the methods and confirmed that they are working. But now I want to use this class to create another class that inherits from LinkedList and also uses Comparable so I can sort values while I enter them. I get everything set up and creates the class
public class SortedLinkedList<T extends Comparable<T>> extends LinkedList<T>{
//And here I try to do something like
#Override
public void add(T x){
//add logic to add a element
}
}
And here I have tried lots of different things. But no matter how I create the method it wont add any new Nodes. I think the problem have to do with the methods not beeing able to access the private Node start from LinkedList. Becuse I can for instance use the add function from LinkedList to just add a element in the same way by doing
#Override
public void add(T x){
super.add(x);
}
And when I tried to just add the methods from LinkedList directly inside SortedLinkedList and changed it to
public class SortedLinkedList<T extends Comparable<T>>{
}
I did manage to use the compareTo() and Override the add method.
I know this got long, but I hope someone can enlighten me on this. I did try to create a getter and setter method inside LinkedList but I didnt manage to get that to compile in any way without errors.
As the JLS states (https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2):
Members of a class that are declared private are not inherited by subclasses of
that class. Only members of a class that are declared protected or public are
inherited by subclasses declared in a package other than the one in which the
class is declared.
You're most likely working with private start variable in your add() implementation in LinkedList class.
To resolve the issue just change the access modifier to protected:
protected Node start;

Meaning of "this" in this code?

public boolean contains(Object o) {
for (E x : this)
if (x.equals(o))
return true;
return false;
}
Can someone tell me what excatly means "this" in this code? Can I write it without this and how?
Here this represents object on which current method was invoked. For instance if you have a.contains(x) then inside contains method this will return reference to same object as held in a reference variable.
Since you ware able to use this in for-each it means that contains method is placed in class which implements Iterable<E> interface because for-each can iterate only over:
arrays like String[] array = ...; for(String s : array){...}
instances of classes which implement Iterable<E> like List<String> where we can write for(String s : list){...}
To avoid this you can explicitly add to your method parameter of class which contains this method, like
public boolean contains(YourClass yc, Object o) {
//and use that parameter in loop instead of `this`
for (E x : yc)
if (x.equals(o))
return true;
return false;
}
but this means you would need to call such method in a way a.contains(a,x) so it needs to repeat a twice (not to mention it can allow us to pass other instance of our class than a like a.contains(b,x)).
To avoid this repetition we can make contains method static which will allow to invoke it via YourClass.contains(a,x). But this way we need to resign from one of basic OOP concepts - polymorphism - since it doesn't work with static methods.
Compiler solves it using first solution, so it compiles our methods like they would be written (and we actually CAN write methods that way) as
public boolean contains(YourClass this, Object o) {
// ^^^^^^^^^^^^^^
...
}
Then when we write a.contains(x) it is compiled as if we would invoke a.contains(a,x).
this is a object of the class that contains your contains() method. It refers to the object of that class for which the method is executed.
Putting it after the : of an enhanced for loop means that the class that contains this method must implement Iterable<E>, since the enhanced for loop can be used to iterate over either arrays or instances of classes that implement the Iterable interface. This means your class is able to iterate over some collection of E elements. E is probably a generic type parameter`.
In order to write your method without this, you would have to supply a reference to some alternative object that implements Iterable<E>, but I don't see the point of doing that.
What exactly means this in this code?
It is always a reference to the current instance. I assume your class implements the Iterable<T> interface and overrides the Iterator<T> iterator() method from it.
The loop is just a syntax sugar for the enhanced for statement. According to the specification (§14.14.2.):
for ({VariableModifier} UnannType VariableDeclaratorId : Expression)
Statement
The type of the Expression must be Iterable or an array type (§10.1), or a compile-time error occurs.
If the type of Expression is a subtype of Iterable, then the translation is as follows.
If the type of Expression is a subtype of Iterable<X> for some type argument X, then let I be the type java.util.Iterator<X>; otherwise, let I be the raw type Iterator.
The enhanced for statement is equivalent to a basic for statement of the form:
for (I #i = Expression.iterator(); #i.hasNext(); ) {
{VariableModifier} TargetType Identifier = (TargetType) #i.next();
Statement
}
Usually, a class implements the Iterable to provide to an API user the ability of being allowed to iterate over the internal collection hiding the actual implementation.
Can I write it without this and how?
Use the logic you have written for the inner iterator.
Use the implementation of the underlying collection (if it's and it suits).
Choose one of the options mentioned above and rewrite into a standard for.
Keyword this is just a reference to the current object.
Here is a example how can be this used:
public class Person {
public final String name;
public Person(String name) {
// name = name;
// which one is an argument, and which one is class field?
// by default, both are reference on argument
// using "this" to access class field
this.name = name;
}
public void copyFields(Person other) {
// current object's reference is the same as other object reference
// in other words "this" and "other" are the same instances
// example:
// Person p1 = new Person("a");
// Person p2 = p1; // p2 is now pointing on the same memory address
// // as p1, so both are pointing on the same object
// // stored in memory.
// p1.copyFields(p2);
if (this == other) { // copying from self? useless...
return;
}
this.name = other.name;
}
}
Anything that implements Iterable interface has method which returns Iterator instance, which is implicitly used by foreach loop to iterate over items hold by object. Iterator
has methods hasNext() which returns true, if there is another object
in iterable container, relative to current position, and next() which returns
next object or throws NoSuchElementException if there is no next object (last invokation of hasNext() has returned false).
Here is a simple example of Iterable implementation with contains methods:
public class Customer extends Person implements Iterable<Item> {
private final List<Item> list = new LinkedList<>();
public final String name;
public Customer(String name) {
this.name = name;
}
public void add(Item item) {
list.add(item);
}
// implementing iterable interface
#Override
public Iterator<Item> iterator() {
return list.iterator();
}
// some contains implementations
public boolean contains1() {
for (Item item : this) { // customer implements Iterable = OK
if (o.equals(item)) {
return true;
}
}
return false;
}
public boolean contains2() {
for (Item item : list) { // list implements Iterable = OK
if (o.equals(item)) {
return true;
}
}
return false;
}
public boolean contains3(Object o) {
for (Iterator<Item> iter = iterator(); iter.hasNext(); ) {
Item item = iter.next();
if (o.equals(item)) {
return true;
}
}
return false;
}
public boolean contains4(Object o) {
for (Iterator<Item> iter = list.iterator(); iter.hasNext(); ) {
Item item = iter.next();
if (o.equals(item)) {
return true;
}
}
return false;
}
public boolean contains5(Object o) {
Iterator<Item> iter = iterator();
while (iter.hasNext()) {
Item item = iter.next();
if (o.equals(item)) {
return true;
}
}
return false;
}
public boolean contains6(Object o) {
Iterator<Item> iter = list.iterator();
while (iter.hasNext()) {
Item item = iter.next();
if (o.equals(item)) {
return true;
}
}
return false;
}
public boolean contains7(Object o) {
return list.contains(o);
}
}
Methods are defined in classes, not in objects.
But they are (generally) invoked from objects.
Methods - as they are defined in classes - don't know in advance which object will call them.
So there is a mechanism (implemented by a hidden parameter this) by which the object - when calling a method - secretively passes the address of itself to parameter this.
(In other programming languages may be used other names, as Me or self.)
I would put it in points for you
When we create a new instance of a class then the non static methods and non static member fields are part of it. We access these methods and fields using . operator.
All the non static method or member fields has access to this. The this keyword simply is a reference to the current object upon which that method is executed upon.
Any class which implements Iterable interface can be used with enhanced For-Loop.
Enhanced for loop uses a syntax
for (Object object : objectOfIterableType)
If the class implementing Iterable interface is parametized, suppose its E. then its what you have to in your code.
for (E x : this)
It means current class has the behaviour of being iterable and can be iterated on the collection of items it holds. Above statement will be executed for each item in the collection of items of type E represented by by the current object referred by this keyword. In each iteration x will represent an item from those contained items.

Categories