#What is a view in java?

118 messages · Page 1 of 1 (latest)

dim hemlock
#

Hello, can someone explain what a view is in java. For e.g, when using Array.asList(), this method returns a view of a list. However, the list isn't like a normal list in terms of we can add something to it or expand it; it's not dynamic. Why even though if we output the instanceof it, it will show List but it isn't "really" a list?

What is the purpose of a view if it doesn't really behave as the data type we want it to?

unkempt yokeBOT
#

<@&987246399047479336> please have a look, thanks.

unreal garden
#

List is an Interface it says "you can use these methods on this instance" but you do not know what kind of list implementation it is. add is a optional operation for List, see here: https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/List.html

void
add(int index, E element)
Inserts the specified element at the specified position in this list (optional operation).

so it is a normal valid List

#

you should not confuse a List with a ArrayList

#

though i would agree that having optional operations in your Intefaces is kinda ass

#

breaks the contract of "the instance of interface X is capable of doing y, z, etc."

thick egret
#

yes, they kinda broke the interface idea, they went too deep in abstract code

dim hemlock
dim hemlock
rich ether
sharp bloom
#

You can use the practice of optional methods, as long as there's a stable type-probe you can use to verify support. Depending on Exceptions is the bad part IMO. They already had the concept of marker interfaces in Java, this would have been a reasonable use.

If they had Collection.Appendable then when generics came along you'd even be able to require it of the caller when passing a List<E> & Collection.Appendable.

rich ether
#
List<Foo> asList(Foo[] array) {
  return new List<Foo>() {
    @Override
    Foo get(int i) { return array[i]; }
    @Override
    void set(int i, Foo foo) { array[i] = foo; }
    @Override
    int size() { return array.length; }
    @Override
    boolean add(Foo foo) { throw new UnsupportedOperationException(); }
    @Override
    void remove(int i) { throw new UnsupportedOperationException(); }
  }
}
#

its a partial implementation of the List interface that delegates to the underlying array

#

and for stuff the array cant do, it simply throws

dim hemlock
#

yepp I see

rich ether
#

generally, such "partial implementations" are discouraged bc they are confusing. but for this one they made an exception. probably bc the use case is too common to not do it

dim hemlock
#

question, why for the add method, we imply that this is an operations that list won't be able to support; is this a design choice or their are some reasons for that?

Alsoo, when we say partial implementation/optional one, we did provide an implementation just that we are throwing an exception saying it's not supported?

rich ether
#

arrays are fixed size. it cant add

#

but list demands the capability to add

#

so thats the problem

#

u have to implement the method to call urself a List

#

but we cant

#

so we throw

sharp bloom
rich ether
#

its confusing ofc if u have a list that cant add/remove. when u give someone a List they expect it to be able to do everything a List can do

#

thats what interfaces are for, after all

#

in a similar way btw there are views to make a normal list into a cant-add-remove-list

#

Collections.unmodifiableList(list)

dim hemlock
#

yep I see, I have an overview of it now, thanks !

rich ether
#

languages like kotlin try to get the difference into the type hierarchy MutableList vs List

#

but in java its too late for sth like that

#

so sometimes we get "full lists", sometimes only "partial lists". and we cant see the difference from outside

unreal garden
rich ether
#

on the topic of calling sth a "view". u notice that those "array-lists" arent using copies of the underlying array. they are using it directly

#

which also means that any change on the array will be seen through the view

#
Person[] array = ...
List<Person> view = Arrays.asList(array);
...
array[0] = new Person("Bob");
Person p = view.get(0); // Bob
#

hence the name "view"

dim hemlock
#

yepp, just read on that, it's the same data structure being used.... question though, are there specific use-cases where we would want to use a view of something, for e.g why would we want to create an array first then later on convert it to another data type

rich ether
#

lets suppose u have an array, have to work with array

#

but then u run into a situation where someone expects a list from u

#

and u cant change it

sharp bloom
#

The term 'view' here is a concept rather than a data-structure

rich ether
#

or u want to utilitze some cool utility method that works with list

#
Person[] array = ...
Collections.shuffle(Arrays.asList(array));
#

not sure if theres also a Arrays.shuffle(...). but if not, u can do it the above way with the view

dim hemlock
#

yep I understand the idea

#

make sense now, thanks !

unkempt yokeBOT
#

@dim hemlock

Your question has been closed due to inactivity.

If it was not resolved yet, click the button below to keep it
open, or feel free to create a new thread.

Note that usually the reason for nobody calling back is that your
question may have been not well asked and hence no one felt confident
enough answering.

When you reopen the thread, try to use your time to improve the quality
of the question by elaborating, providing details, context, all relevant code
snippets, any errors you are getting, concrete examples and perhaps also some
screenshots. Share your attempt, explain the expected results and compare
them to the current results.

Also try to make the information easily accessible by sharing code
or assignment descriptions directly on Discord, not behind a link or
PDF-file; provide some guidance for long code snippets and ensure
the code is well formatted and has syntax highlighting. Kindly read through
https://stackoverflow.com/help/how-to-ask for more.

With enough info, someone knows the answer for sure 👍

dim hemlock
#

Hello, quick question, when we talk about List, normally it's an interface, right? Meaning we can't instantiate it.

However, consider the following:

 List<Person> people = List.of(
            new Person("Jess", 29),
            new Person("Sally", 72),
            new Person("Bess", 41)
        );

List.of returns a list, is it the same thing as if we are instantiating a list here? (well, ig the answer is no? But why, how is it different, what are we doing here?)

unkempt yokeBOT
woeful elm
#

if you trace List.of() it comes back to a ListN<?> which is an AbstractImutableList, which is an implementation of List

#

List.of() returns a type of List

#

the <E> List<E>

dim hemlock
#

yeah, just tried that in my ide

#

<E> List <E> is a class?

#

it's not a "direct" List which is being returned?

woeful elm
#

the <E> List<E> is returning a type of the type mentioned

#

Generics are fun

dim hemlock
#

hmmm wait im trying to make sense of that generic

woeful elm
#

So the type returning is an ImutableCollection

dim hemlock
#

oh

woeful elm
dim hemlock
#

yeah I see

#

yep make sense, will stick to that for now, still confuse about the <E> List<E> though, I don't know how to read it 😭

woeful elm
#

We need a type of E, this can be anything, but we're going to return a tyee of ImutableCollection.List12(),

#

because it has to be of type List

#

the first isolated <E> is the return type, and thanks to Generics, it can return an unspecified type.

#

as long as it extends or implements, the right hand side List<E>

dim hemlock
#

yepp I see

woeful elm
#

The use of E I am sssuming is the confusing part

dim hemlock
#

I didn't understand why we have ! <E!>, like what's the exclamation doing in this scenario

rich ether
woeful elm
#

I thought it was JetBrains specific but I was fact checking, thanks

rich ether
#

they run static code analysis and then show stuff like that. its just extra info, so to speak

dim hemlock
#

oh ok, it's clearer in my head now

#

thanks !!

woeful elm
#

Normally anything in that grayed out box, like the !, are Intellij code-tips

#

likea heads up display

dim hemlock
#

yep, will remember that for the future

woeful elm
#

Hover over them

dim hemlock
#

btw in this case it means, we expect "any type" except null?

woeful elm
#

It has to have a Type to be created, so cannot be a null type

#

can't create Nothing, it already exists 😄

dim hemlock
#

yep I see

rich ether
#

null isnt a type

#

its a "value"

#
Foo foo = null;
#

the type is Foo

#

the "value" of the variable foois null

#

meaning its currently not pointing to any instance of Foo

dim hemlock
#

yeah u r right, just realised that I never did something like Null variable...

rich ether
#

intellij ran static code analysis on the code and found out that its currently not possible for the thing to be null

#

hence they show !

dim hemlock
#

oh ok

distant mauve
#

you could read Foo! as "Foo and its definitely not null"

#

Foo as "Foo and maybe its null we have no clue"

rich ether
#

(at least currently. theres no guarantee someone wouldnt change the code in the future and then it may become null)

distant mauve
#

Foo? as "Foo and its going to sometimes be null"

dim hemlock
rich ether
#

the classic use case (which was replaced by Optional a few versions ago) is one example that is still very common:

#
User findUser(int id) { ... }
#

null for "user doesnt exist"

#

nowadays ud prefer to write this as Optional<User> but theres still plenty of old code around and also situations in which u wouldnt use Optional

#

for example for code that is close to its users and small in scope (e.g. fields or private methods)

#
User user = null;
try {
  ... // lets find the user
}
if (user == null) { ... }
#

u likely had such a situation as well already in a method

#

where u first made sth null and then tried to give it a value afterwards

#

and then have the situation where it might still be null if sth went wrong or unexpected

dim hemlock
#

oh ok I see

#

yepp got it, thanks !

rich ether
#

so that user variable would, in jetbrains annotations, be of type User?

#

"sometimes value, sometimes null"

#

theres also a java annotation library that is sometimes used in projects which adds @NonNull and @Nullable annotations. thats quite similar. just that in that case the programmer adds the annotations to the variables manually to express intention

#

whereas the jetbrains thing is an automatic analysis on the current code paths

#

so just represents "current state" and not "developer intention"

dim hemlock
#

yeah I see, I think I noticed that in spring when I was watching a collegue working