Java interface and extending ArrayList [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am trying to understand Java and I found this code in a text book:
public EArrayList filt(Func a)
{
}
where apply is in an interface called Func
I understood that this method applies a function filter on a list and returns a new list filtered. However I can't understand why Object elem is used. I tried the code and it won't work if I rename Object.
Also I can't understand the following line:
if((Boolean)a.apply(elem) == true)
(what does Boolean stand for apart from return type)
Can someone send me a good link to understand better how this works since I searched a lot about interfaces and never came across this format.

...However I can't understand why Object elem is used.
The likelihood is that EArrayList extends ArrayList, but doesn't give it a type bound - hence, it can hold any object.
Typically, you find Lists with some type bound, such as List<String>, or List<Integer>. If you omit that, then you are dealing with only Objects.
You're also doing it again with Func a - it has a type bound of <S, T>, which one could presume that you're going from a type of S to a type of T. But that is omitted as well, so you're only dealing with Func<Object, Object>.
That's where this cast comes from:
(Boolean)a.apply(elem)
You can omit the == true part. You're checking boolean values.
Java only knows that it is returning an Object from apply, but you don't want an Object - you want a Boolean. Java will attempt to cast it to a Boolean for you, if it can be cast to one. That could blow up at runtime, which means that this particular piece of code is a bug waiting to have a AbstractObjectFactoryImpl inserted into the list, waiting to try to be cast to a Boolean.
This is why you want to use Generics. They protect you from runtime failures like that by enforcing this stuff at compile time, virtually eliminating type casts.
Had this been done with generics, you would see declarations like this:
// Assuming that there is a generic type T on the class:
public EArrayList<T> filter(Func<Boolean, T> a) {
int size = size();
EArrayList<T> arr = new EArrayList<T>();
for(int i = 0; i < size; i++) {
T elem = get(i);
if(a.apply(elem)) {
arr.add(elem);
}
}
return arr;
}

Related

add null in the list of model data arrays kotlin android [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
Why can't I add null in the list of model data arrays in Kotlin language?
enter image description here
adapterPaging!!.setOnLoadMoreListener {
var customersModels: List<CustomersModel> = ArrayList()
customersModels.add(null)
}
var customersModels: List<CustomersModel> = ArrayList()
Your problem(?) here is polymorphism. You've defined customersModels as a List, which in Kotlin is explicitly immutable. You can't add things to it.
Methods in this interface support only read-only access to the list; read/write access is supported through the MutableList interface.
You're assigning an ArrayList to that variable, which is an object that does have the add method. And an ArrayList is a List, so you can do that. Like how a pencil is a writing tool that's erasable, if someone just needs something to write with, you can give them a pencil or a pen. All they've asked for is something that writes.
But the variable you're interacting with, customersModels, is explicitly a reference to a Kotlin List - a more restrictive subtype of MutableList*. It knows nothing about what that object actually is, just that it fits the immutable List type. That type does not have an add method so you can't call it. Same as how if you ask for a writing tool, you can't assume you'll be able to erase what you write.
So you have three options here (let's not get into reflection):
You can cast that variable to another type:
// or 'as ArrayList' if you really need to be that specific for some reason - you probably don't
(customersModels as MutableList).add(thing)
This is an unchecked cast - you're telling the compiler "hey I know what this is, you don't but you're just gonna have to trust me on this one". This is unsafe, because there's no protection, the compiler can't do any checking and force you to handle potential problems. (Don't do this)
A better approach is to actually check as you cast - there are two ways to do this in Kotlin:
// confirm the object's type - this will result in a 'smart cast' because the compiler
// can see that you're handling it safely, so it basically allows you to treat
// myList as that type
if (myList is MutableList) myList.add(thing)
// same deal but you can cast with a null fallback if it fails, then null-check the result
(myList as? MutableList)?.add(thing)
This is good for things where you handle a more general type, but you might want to get specific and handle different member types in different ways. Especially common if you're using sealed classes.
The last approach is to just use the appropriate type in the first place!
// MutableList, since you want to mutate it by adding stuff
var customersModels: MutableList<CustomersModel> = ArrayList()
customersModels.add(null)
You're creating a list you want to change - so that's a MutableList, and that's what customersModels should be. This kind of thing can be internal - you can expose that list as a List rather than a MutableList, so that other stuff that uses it sees it as a fixed, immutable list. If you've used LiveData you've probably seen this approach:
private val _myData = MutableLiveData<String>("hi")
val myData: LiveData<String> = _myData
myData is literally pointing at that MutableLiveData object, but because its type is just LiveData (the immutable kind) that means stuff that accesses that public variable see an object they can't change. Really they could cast it to MutableLiveData and mess with it, but it's less a security feature and more of an organisational thing. Make it clear how stuff is meant to be used, how you interact with it, etc. If you want to update, go through a specific function, that kind of thing.
So use List if it's just a list that's meant to be read, not written to. If it will/might be changed, use the MutableList type. This makes it clearer about what's going on.
Also, generally you shouldn't use explicit types like ArrayList - Kotlin has a bunch of functions to generate Lists and MutableLists, which makes it easier to reason about what you're doing and why:
val numbers = List(5) { it + 1 }
val greetings = mutableListOf("hi", "hey", "sup")
Notice I'm not specifying the type next to the variable, it's getting inferred by the function I'm using. So there's no "treat this mutable list as an immutable one" going on (unless you need to do that for a specific reason!)
Your customersModel POJO class must contain a nullable data type. and also you have to declare list as follow :-
var customersModels: ArrayList<CustomersModel?> = ArrayList() CustomersModel must be Then you will add null values to the list.

Java list default implementation? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
If I declare a new list like this:
List<String> listExample = someFunction();
what list interface implementation will be used?
EDIT: Thanks for the answers so far. What is considered as the clean way to do this, should I always declare list with new?
As Eran commented that totally depends on what someFunction(); returns .Both ArrayList<E> and LinkedList implements List interface .
You can try ,
System.out.println("" + listExample.getClass());
to find out the which has been implemented. From docs,
public final Class<?> getClass()
Returns the runtime class of this Object. The returned Class object is
the object that is locked by static synchronized methods of the
represented class.
Whatever you are building e.g. LinkedList, ArrayList, Vector, Stack in and returning from someFunction() will be implemented with listexample. If you are using List interface reference, it has one benefit, that you can assign any type of object to it (LinkedList, ArrayList, Vector, Stack).
eg if u give
List listExample = new ArrayList();
Then the Object will be created for ArrayList and list is just an instance of listExample.
and you can use getClass() for that listExample to view

JAVA variable as 2 types [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
How can I create value of type String and also Collection?
I want someTimes put in this Strings and the othertimes put collections.
for example in javascript I would do
var k;
if (someBoolean){
k=1;
} else{
k=[1,2,3];
}
can I get this behavior of the variable in java, hack or something?
I found Solution: I created an interface and declear this Objects as this interface.
Java does not support union types; however, both of these types share the same base Object class, so you could assign either one of them to a variable defined like this
Object something;
something = "Hello World!";
something = new ArrayList(); // this is a collection.
Odds are that you probably were thinking of a Collection of Strings, in which case, you define it like Collection<String>
Collection<String> strings = new ArrayList<String>();
strings.add("Hello");
strings.add("World");
strings.add("!");
If that's not what you wanted, and you really want to sometimes store a String and sometimes store a Collection, remember that Java enforces strict type checking. This means that variables cannot just store anything, they must store something that is type compatible.
String and Collection are too different to be considered type compatible without some seriously bad programming (like using Object) or something even stranger.
You cant. String is a final class, meaning you cannot extend upon it. A String will only ever be a String. You can have a collections that contain Strings, but a String object will only have 2 types: Object and String.
You can have a class that contains a String (or a StringBuilder) and a collection, then use that class to store/receive from

Why those methods which are used has just one parameter although methods require values of two elements? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Class Alkio of my previous! question is chosen to do more methods.
Implement to the class in addition to the previous ones following
methods:
public boolean suurempiArvo(Alkio verrattava)
and
public int compareTo(Alkio verrattava)
Method suurempiArvo returns true, if the value of the object is
greater than value of verrattava. Method compareTo compares the
values of elements and returns an integer( negative, if the value of
the object is less that value of verrattava, zero, is values are the
same and otherwise positive)
Questions.
Why those methods which are used has just one parameter although methods require values of two elements? If I refer in the methods to verrattava by writing verrattava, how do I refer to object?
When you have a method
public int compareTo(SomeObject other) {
// needs implementation
}
You are comparing other with the current instance. That is to say, the reason why you do not need the second element in the signature is that the second element is already there, it's the object whose method is being invoked. You compare the members of other with the members of the present instance, basically this, in order to arrive at the proper result.
public int compareTo(SomeObject other) {
// assumes member variable foo
if (this.foo > other.foo) {
// you finish implementation
}
}
For clarification, if you were to invoke these methods, it would be something like
SomeObject first = new SomeObject();
SomeObject second = new SomeObject();
int result = first.compareTo(second);
So you pass the second object into the compareTo method of first. first then compares itself against the second (this vs. other).
Object would appear to refer to the instance of the Alkio class that you're calling the method on, so you'd refer to it using this.
You should refer to a tutorial on Java classes - and also the compareTo method of Comparable interface. The simple answer to your question is that you are dealing with two objects: verrattava' and the object itself, referrd to withthis, e.g.this.value1`.
Take a look at this article - it's not very well formatted, but does give you the idea - scroll down to an example at the bottom.

Creating an array of generic collections

Actually, the question should be
Creating an array of generic anything.
Why can't the compiler take care of it?
The following would be flagged as an error - cannot create generic array.
List<MyDTO>[] dtoLists = {new ArrayList<MyDTO>(), anExistingDtoList};
To overcome that, I need to
List<MyDTO>[] dtoLists = (List<MyDTO>[])Array.newInstance(ArrayList.class, 2);
dtoLists[0] = new ArrayList<MyDTO>();
dtoLists[1] = anExistingDtoList;
So, why can't the compiler convert the first case into the second case?
I do realise that generics are compile-time determinate and not run-time determinate, while arrays are run-time determinate and therefore need a determinate type in order to create an array.
What are the technological/logical barriers compiler designers would encounter that would prevent them being able to implement this?
Is the issue purely philosophical, concerning language orthogonality? If so, how would such a behaviour violate language orthogonality?
Is it a question of complexity? Explain the complexity.
I am hoping answers to my question would give me better insight into java compiler behaviour when it concerns generics.
Side note:
c'mon stop being trigger happy. The answers Array of Generic List
do not answer my question. Why can't compilers spontaneously perform the conversion?
Actually Java does create generic array for varargs, so you can do
List<MyDTO>[] dtoLists = array(new ArrayList<MyDTO>(), anExistingDtoList);
#SafeVarargs
static <E> E[] array(E... array)
{
return array;
}
As to why is explicit generic array creation forbidden, it has something to do with type erasure. (The same concern exists in the above solution, but suppressed by #SafeVarargs) However it is debatable; there are different ways to handle the concern, a compiler warning is probably enough. But they chose to outright ban it, probably because arrays are no longer important anyway now that we have generic collections
I do know that, relative to the workarounds to this issue, Array.newInstance() is an expensive method to call. IIRC it uses a native method to instantiate the array, amidst the other reflection involved. I can't offer any statistics, but this seems like a good enough reason for such functionality not to be automatically substituted in by the compiler in order to allow generic array creation. Especially given the existence of ArrayList, etc. it just doesn't seem like a pressing issue.
Compilers can spontaneously perform the conversion, they are just specified not to because generic arrays can't behave like non-generic arrays.
See 10.5. Array Store Exception:
For an array whose type is A[], where A is a reference type, an assignment to a component of the array is checked at run time to ensure that the value being assigned is assignable to the component.
If the type of the value being assigned is not assignment-compatible with the component type, an ArrayStoreException is thrown.
If the component type of an array were not reifiable, the Java Virtual Machine could not perform the store check described in the preceding paragraph. This is why an array creation expression with a non-reifiable element type is forbidden.
A List<MyDTO>[] would not throw if we put some other kind of List in it, so it doesn't behave as an array. Note the last sentence from the quote: "This is why an array creation expression with a non-reifiable element type is forbidden." This is the reason, it's specified to be so. (And, for the record, this reasoning has always existed, so it was present when the question was posted in 2011.)
We can still do this:
#SuppressWarnings({"unchecked","rawtypes"})
List<MyDTO>[] dtoLists = new List[] {
new ArrayList<MyDTO>(), anExistingDtoList
};
Or this:
#SuppressWarnings("unchecked")
List<MyDTO>[] dtoLists = (List<MyDTO>[]) new List<?>[] {
new ArrayList<MyDTO>(), anExistingDtoList
};
(Besides statically checking the argument types, the varargs thing is equivalent: it creates a List[] and suppresses warnings.)
Now, sure, the specification could be changed to something like "If the type of the value being assigned is not assignment-compatible with the raw type of the component type...", but what is the point? It would save a handful of characters in some unusual situations but otherwise suppress warnings for those who don't understand the implications.
Furthermore, what the tutorial and other typical explanations I've seen don't demonstrate is just how baked in to the type system covariant arrays are.
For example, given the following declaration:
// (declaring our own because Arrays.fill is defined as
// void fill(Object[], Object)
// so the next examples would more obviously pass)
static <T> void fill(T[] arr, T elem) {
Arrays.fill(arr, elem);
}
Did you know that this compiles?
// throws ArrayStoreException
fill(new String[1], new Integer(0));
And this compiles too:
// doesn't throw ArrayStoreException
fill(dtoLists, new ArrayList<Float>());
Before Java 8, we could make those calls to fill fail by giving it the following declaration:
static <T, U extends T> void fill(T[] arr, U elem) {...}
But that was only a problem with type inference, and now it works "correctly", blindly putting List<Float> in to a List<MyDTO>[].
This is called heap pollution. It can cause a ClassCastException to be thrown sometime later, likely somewhere completely unrelated to the actions that actually caused the problem. Heap pollution with a generic container like List requires more obvious unsafe actions, like using raw types, but here, we can cause heap pollution implicitly and without any warnings.
Generic arrays (and really, arrays in general) only give us static checking in the simplest of circumstances.
So it's evident that the language designers thought it was better to just not allow them, and programmers who understand the problems they present can suppress warnings and bypass the restriction.

Categories