Patterns for arrays of specific length
forax at univ-mlv.fr
forax at univ-mlv.fr
Mon Mar 4 12:18:26 UTC 2019
----- Mail original -----
> De: "Tagir Valeev" <amaembo at gmail.com>
> À: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Envoyé: Lundi 4 Mars 2019 10:13:40
> Objet: Re: Patterns for arrays of specific length
> Hello!
>
>> Arrays.stream(resolveResults).findFirst().filter(ResolveResult::isValidResult).map(ResolveResult::getElement).orElse(null)
>
> This is obviously wrong: we need to return non-null result only if
> there's exactly one resolve result. As IDE we need to support
> incorrect code, in particular where reference resolves to several
> symbols (e.g. ambigous method overload), but in most of the places we
> want to proceed further only if the resolve result points to exactly
> one symbol.
oops, forget a filter
Arrays.stream(resolveResults).filter(results -> results.size() == 1).findFirst().filter(ResolveResult::isValidResult).map(ResolveResult::getElement).orElse(null)
or only using Optional
Optional.of(resolveResults).filter(results -> results.size() == 1).map(results -> results[0]).filter(ResolveResult::isValidResult).map(ResolveResult::getElement).orElse(null)
>
> We could use a third-party collector, like in my StreamEx lib:
> StreamEx.of(resolveResults).collect(MoreCollectors.onlyOne()).filter(ResolveResult::isValidResult).map(ResolveResult::getElement).orElse(null)
>
> That would be technically correct, but I really worry about amount of
> garbage created in such kind of code (the same concern applies to your
> version as well). For us GC pressure is very important (you may
> imagine amount of reports "IDEA eats insane amount of memory", "IDEA
> stuck in garbage collection" and good old "IDEA is slow" we receive)
> and when allocation-free version of the code is not much longer, I
> would certainly prefer it.
I believe the verson with only Optional should be OK, the VM tends to do a very good job not allowing them,
obviously, it will be better when Optional will be a tru value type.
and a solution to avoid IDEA to eats too much memory is to pass the Collector to multiResolve so you can call with a collector that reduce to an Optional (your MoreCollectors.onlyOne()) or a List depending if you want only one result or all results.
>
> With best regards,
> Tagir Valeev.
Rémi
>
>>
>> and obviously, the method should return an Optional instead of calling
>> orElse(null) at the end.
>>
>> Rémi
>>
>> >
>> > I wonder if special kind of patterns to cover such case could be invented like
>> >
>> > return multiResolve(false) instanceof ResolveResult[] {var res} &&
>> > res.isValidResult() ?
>> > res.getElement() : null;
>> >
>> > In essence it should be a deconstruction pattern for arrays. I don't
>> > remember whether it was discussed, but probably I'm missing something.
>> >
>> > Alternatively this could be covered by utility method like
>> >
>> > static <T> T getOnlyElement(T[] array) {
>> > return array.length == 1 ? array[0] : null;
>> > }
>> >
>> > return getOnlyElement(multiResolve(false)) instanceof ResolveResult
>> > res && res.isValidResult() ?
>> > res.getElement() : null;
>> >
>> > But this doesn't scale for arrays of bigger length.
>> >
>> > With best regards,
> > > Tagir Valeev.
More information about the amber-spec-experts
mailing list