Create a Class That extends Java.util.ArrayList - java

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

Related

Trying to modify Java Vector's get() to make new T() if the element is null

I'm Trying to modify Java Vector to raise size if im accessing an element bigger than the vector's size. And to insert a new element if im accessing a not initialized element.
Eclipse throws cannot instantiate the type Obj.
public static class Vec<Obj> extends Vector<Obj> {
#Override
public Obj set(int a, Obj b) {
if (super.size()<=a) super.setSize(a+1);
return (Obj) super.set(a,b);
}
#Override
public Obj get(int a) {
if (super.size()<=a) super.setSize(a+1);
if (super.get(a)==null) super.insertElementAt( new Obj() , a);
return (Obj) super.get(a);
}
public Vec () {
super();
}
}
There is no guarantee that T has a no-args constructor. Also, people like to use interfaces, so there's a good chance T wont be concrete.
So, supply an abstract factory to the construction of your Vec. A suitable type is java.util.function.Supplier<T>.
private final Supplier<T> dflt;
public Vec(Supplier<T> dflt) {
super();
this.dflt = Objectes.requireNonNull(dflt);
}
...
if (super.get(a)==null) {
super.insertElementAt(dflt.get(), a);
}
Construct as:
Vec<Donkey> donkeys = new Vec<>(BigDonkey::new);
java.util.Vector methods should be synchronized, although such locking isn't really useful and ArrayList should generally be used instead. Even then, subclassing like this breaks LSP.

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.

Get return statements in a java method

How can I get all possible return values of a method in java?
Example:
Object onEvent() {
if (condition) {
return "a";
}
if (condition2) {
return "b";
}
if (condition3) {
return "c";
}
}
I need something like this:
String[] returns = Utils.getReturnStatements("object.onEvent()");
returns = ["a", "b", "c"]
You can only retrieve the method signature, which in this case would be Object as the return type.
To get the any more details you need to either statically analyze the source code or return a type such as an enum.
If you only need to analyse simple methods that return constant values such as the one in your example, then you can do this relatively easily via a static analysis using ASM or a similar bytecode toolkit.
For methods matching the structure of your example (i.e that only directly return constants) you just need to look for the pattern
LDC ???
ARETURN
And collect the constants loaded with LDC. This would be very straightforward.
If the methods can be more complex, e.g if they return values assigned to variables, then you will need to perform a flow analysis. This is much more work, but ASM provides support.
If the methods you are analysing return values other than simple constants then it will be incredibly difficult/impossible to do this via static analysis.
You can't do such a thing in Java, but you can do something like this:
Object onEvent() {
List<String> list = new ArrayList<String>();
if (condition) {
list.add("a");
}
if (condition2) {
list.add("b");
}
if (condition3) {
list.add("c");
}
return list.toArray();
}
And then:
String[] returns = (String[])MyObj.onEvent();
First remove multiple returns:
Also to get all return types just pass a List of object to your method and change the onEvent code like this:
Object onEvent(List<Object> rets) {
String ret = "";
rets.add("a");
rets.add("b");
rets.add("c");
if (condition) {
ret = "a";
}
if (condition2) {
ret = "b";
}
if (condition3) {
ret = "c";
}
return ret;
}
Make a call to onEvent like this:
List<Object> returns = new ArrayList<Object>();
Object retVal = obj.onEvent(returns);
As #Johan said, it is not possible. The only way if you really need it would be for you to store these possible results in a Map mapping the method name to a List or array, or better, use an enum if possible.
Edit:
After reading your comment, I think you should use a HashMap with a Node as the key and a List as value. When you analyse a Node you create the list of exit Nodes in a list, and then map that list to the node.
With use of the command pattern and enum there is a workaround.
public class OnEvent implements Command<EventInfo> {
#Override
public EventInfo execute() {
// do some checking
return EventInfo.A;
}
#Override
public EventInfo[] getValues() {
return EventInfo.values();
}
public static void main(String[] args) {
OnEvent e = new OnEvent();
EventInfo retVal = e.execute();
EventInfo[] values = Utils.getReturnStatements(e);
}
}
enum EventInfo {
A, B, C;
}
interface Command<TYPE extends Enum<?>> extends KnownReturnValues<TYPE> { public TYPE execute(); }
interface KnownReturnValues<TYPE> { public TYPE[] getValues(); }
class Utils {
private Utils() {}
public static <TYPE extends Enum<?>> TYPE[] getReturnStatements(Command<TYPE> c) {
return c.getValues();
}
}
Its not really good programming practice, but you can create a class with 3 public data members, and have your code look something like this. (Ill call the class "myclass")
public a, b, c = null;
//And then your main class would look something like this
if (condition){
myclass.a=whatever;
}
else if (condition){
myclass.b=whatever;
}
else if (condition){
myclass.c=whatever
}
Then you would need another control structure that said something along the lines of
if (myclass.datamember!=null) to make sure you have values in the class data members. Again, this is not good programming practice, but it will work for what you want.

Overloading / generics in Java

I want to run certain tests in Lists. The Lists can contain entirely different classes.
I have one method to check the consistency of the list - not null, not empty, no more than x elements. This is common to all the lists. Then I want to test each of the objects, using overloading.
The idea would be something like:
public static <T> void check(List<T> list) {
//do general checks
for (T element : list) {
check(element);
}
}
and then
public static void check(SomeType element) {...}
public static void check(SomeOtherType element) {...}
But I also had to add a method like this:
public static void check(T element) {...}
And this was called at runtime - not my other methods with the specific classes. Although the class was exactly the same. I'm evidently missing some generics understanding.
Now if I don't use the general method at all and try to solve it this way:
public static void check(List<SomeType> list) {...}
public static void check(List<SomeOtherType> list) {...}
Compiler error - "Method check(List) has the same erasure check(List) as another method..."
So is there any elegant solution for this? I could just use different method names but would like to know how it's possible without that.
Thanks!
This isn't something about generics that you're missing. Java does not have double dispatch. The call to check must be resolved at compile-time, and check(T) is the only match since the compiler can't tell if T is SomeType or SomeOtherType in a given scenario. It needs to choose one method to call that will work for all possible Ts.
This is sometimes solved using the visitor pattern.
The problem should be solved by the caller. When it instanciate your class with a concrete type for T, it should also pass an instance of Checker<T> with the same concrete type:
public class SomeClass<T> {
private List<T> list;
private Checker<T> checker;
public SomeClass(Checker<T> checker) {
this.checker = checker;
}
public void check() {
checker.check(list);
}
}
public interface Checker<T> {
public void check(List<T> list);
}
...
SomeClass<Foo> someClass = new SomeClass<Foo>(new Checker<Foo>() {
#Override
public void check(List<Foo> list) {
// do whatever you want here
}
});
You can use instanceof to dispatch:
public static <T> void check(List<T> list) {
for (T element : list) {
check(element);
}
}
public static void check(T t) {
if (t instanceof SomeType) {
SomeType someType = (SomeType) t;
// code for SomeType ...
} else if (t instanceof OtherType) {
OtherType otherType = (OtherType) t;
// code for OtherType ...
} else {
// we got a type that we don't have a method for
}
}
With generics, the type parameter is actually erased during compilation, and the list object don't know anything about the static type of the object it contains. Since it doesn't know it, it can not use overloading to call methods with different parameters, because Java doesn't support multiple dispatch.
You have then three choices:
Make your objects implement a Checked interface with a check method that does the check logic. Downside is that the check logic is now dispersed in several places and it is not practical if you have objects of classes you don't have control of.
Use instanceof to call explicitly the check methods according to the dynamic type of the object. Downside is you potentially end up with a big if/else block a bit harder to maintain.
Implement the visitor pattern. Downside is that you have to change the object classes too, but the check logic stay in a single place.
Since the type of the variable is lost in check(List<T> list) you have two options:
1. Do different things by checking runtime type
check(T element) {
if (element.getClass().equals(SomeType.class)) {
check((SomeType) element);
} elseif (element.getClass().equals(SomeOtherType.class)) {
check((SomeOtherType) element);
}
This can be made a little more sophisticated, for example by wrapping each check in a Callable and using a Map<Class, Callable>
This is similar to visitor pattern.
2. Calling a virtual method on the element to be checked itself
If the checking logic can be pushed to the object to be checked itself (this is not necessarily a bad thing) then you don't need to check types:
interface Checkable { void check(); }
class SomeType implements Checkable { .... }
class SomeOtherType implements Checkable { .... }
Then:
public static <T extends Checkable> void check(List<T> list) {
for (T element : list) {
element.check();
}
}
These are the only two options, any implementation has to be a variation on one of these

Accessor methods for Collections in Java

Given a generic class:
class MyClass (
private List l = new LinkedList <String>();
public void addElement (String s) (l.add (s);)
.............
)
an accessor method that allows me to iterate on the list as it should be?
I had decided to implement a method that returns an iterator directly, but does not seem correct because it could change the list from the outside with remove ().
What do you think?
import java.util.*;
public Iterator<String> elements() {
return Collections.unmodifiableList(elements).iterator();
}
If you don't mind exposing the fact that the elements are stored as a List, you could also use do:
public ListIterator<String> elements() {
return Collections.unmodifiableList(elements).listIterator();
}
If you want to allow callers to use the "foreach" syntax, you might want to return an Iterable:
public Iterable<String> getElements() {
return Collections.unmodifiableList(elements);
}
And, again, if you don't mind exposing that the elements are returned as a List, this last solution could return List<String>
Most common way would be to implement Iterable interface but since you don't want to expose remove method you can follow the advice from NamshubWriter or provide your implementation of get(index) and size() methods (assuming your class should behave like a List). This will allow index based iteration.
however such a thing would be fine?
public Iterator<String> getList(){
return new Iterator<String>(){
Iterator<String> i=l.iterator();
public boolean hasNext() {
return i.hasNext();
}
public String next() {
if(!i.hasNext()) throw new NoSuchElementException();
return i.next();
}
public void remove() {
throw new UnsupportedOperationException();
}
}
}
need a method that let me just browse the collection elements and preserve encapsulation, method unmodifiable ... I know but I can not use it.

Categories