• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag
 

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: NScollections vs Java collections
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NScollections vs Java collections


  • Subject: Re: NScollections vs Java collections
  • From: Hugi Thordarson via Webobjects-dev <email@hidden>
  • Date: Mon, 03 Feb 2025 13:12:15 +0000

Hi Samuel,

Yes, we have a very nice querying API/syntax similar to ERXKey in Cayenne
(although they’re called “Properties” in the Cayenne world).

For example, selecting all my receipts, ordering them by date and prefetching
their entries:

====
ObjectSelect
        .query( Receipt.class )
        .where( Receipt.USER.dot( User.NAME ).eq( “Hugi Þórðarson” ) )
        .orderBy( Receipt.SHOP ).dot( Shop.NAME ).desc() )
        .prefetch( Receipt.ENTRIES.joint();
        .select( objectContext );
====

They’ve also evolved quite a bit in the last years along with Cayenne’s
SQL/querying abilities and now include fun stuff like SQL subqueries,
aggregates, functions and features like EXISTS and HAVING. So for a more
complex example, selecting a [Receipt]’s date/total, the related [Shop]’s name,
the number of it’s related [Entry] records, with a creation_date in year 2023,
where they have more than five entries, a higher total than 1.000 and have a
related OcrResult object (nonsensical query, but yeah… it’s a demo):

====
ObjectSelect
        .query( Receipt.class )
        .columns(
                Receipt.DATE_ONLY,
                Receipt.TOTAL_AS_WRITTEN_ON_RECEIPT,
                Receipt.SHOP.dot( Shop.NAME ),
                Receipt.ENTRIES.count()
        )
        .where(
                Receipt.USER.dot( User.NAME ).in( "Hugi Þórðarson", "Ósk
Gunnlaugsdóttir" )
                        .andExp( Receipt.CREATION_DATE.year().eq( 2023 ) )
                        .andExp( Receipt.OCR_RESULTS.exists() )
        )
        .having(
                Receipt.ENTRIES.count().gt( 5l )
                        .andExp( Receipt.TOTAL_AS_WRITTEN_ON_RECEIPT.sum().gt(
BigDecimal.valueOf( 1000 ) ) )
        )
        .orderBy(
                Receipt.ENTRIES.count().desc()
        )
        .select( oc );
====

… generating the following SQL:

====
SELECT "t0"."date_only", "t1"."name", COUNT( "t2"."id" ),
"t0"."total_as_written_on_receipt" FROM "fd_receipt" "t0" JOIN "fd_shop" "t1"
ON "t0"."shop_id" = "t1"."id" JOIN "fd_entry" "t2" ON "t0"."id" =
"t2"."receipt_id" JOIN "fd_user" "t3" ON "t0"."user_id" = "t3"."id" WHERE (
"t3"."name" = ? ) AND ( EXTRACT(YEAR FROM "t0"."creation_date") = ? ) AND
EXISTS (SELECT "t4"."id" FROM "fd_ocr_result" "t4" WHERE "t4"."receipt_id" =
"t0"."id") GROUP BY "t0"."date_only", "t1"."name",
"t0"."total_as_written_on_receipt" HAVING ( ( COUNT( "t2"."id" ) > ? ) AND (
SUM( "t0"."total_as_written_on_receipt" ) > ? ) ) ORDER BY COUNT( "t2"."id" )
DESC [bind: 1->name:'Hugi Þórðarson', 2:2023, 3:5, 4:1000]
====

This showcases just a part of the features, and works so well it feels almost
magical at times. I could also have specified Receipt.SELF as a “column”
instead of fetching specific values of the Receipt entity, meaning I get the
entire Receipt object (with all it's associated ORM features) along with it’s
aggregate values. I use this quite a lot (didn’t do that in the example since
it makes the resulting SQL longer, since there’s a lot of columns involved).

And yes, you can use Properties to perform in-memory operations like filtering
and sorting.

Receipt.CREATION_DATE.desc().orderedList( receipt );
Receipt.USER.dot( User.NAME ).eq( “Hugi” ).filterObjects ( receipts );

Cheers,
- hugi



> On 3 Feb 2025, at 12:18, Samuel Pelletier via Webobjects-dev
> <email@hidden> wrote:
>
> HI,
>
> Those NS collections where essentials in the first java WO mainly because at
> that time Java did not had real collections classes (they appeared in Java
> 1.8), and the name was probably kept to help porting. I did not switch to
> java WO at that time and maintained some objective-C apps for a long time!
>
> I mostly use the NS versions because I'm still on EOF and uses ERXKey for
> sort orderings, qualifier building and aggregate computation to have type
> checking:
>
> - EOQualifier qualifier =
> Evenement.DATE.greaterThanOrEqualTo(dateDebut()).and(Evenement.DATE.lessThanOrEqualTo(dateFin()));
> - ERXKey.sum(ContratRetenue.NB_HEURES).valueInObject(retenues);
> - NSArray<Etudiant> etudiants =
> Groupe.ETUDIANTS_ACTIFS.atFlatten().arrayValueInObject(evenement.groupes());
> -          sortOrderings = Evenement.DATE.asc()
>         .then(Evenement.ORDRE_AFF_MOIS_SALLE.asc())
>
> .then(Evenement.GROUPE_PRINCIPAL.dot(Groupe.SEMESTRE_DEBUT.dot(Semestre.DATE_DEBUT)).desc()
>         .then(Evenement.HEURE_DEBUT.asc()));
>
> I still think those are more readable than creating lambda, probably mostly
> explained because I'm use to the syntax.
>
> Is there something like ERXKey when using Cayenne ?
>
> Regards,
>
> Samuel
>
>
>> Le 2 févr. 2025 à 07:21, Amedeo Mantica via Webobjects-dev
>> <email@hidden> a écrit :
>>
>> Iirc the NS collections were there due to simplifying porting of apps from
>> objc to Java. I don’t think there is any big difference in performance
>>
>> Sent from my iPhone
>>
>>> On 2 Feb 2025, at 12:18, Jérémy DE ROYER via Webobjects-dev
>>> <email@hidden> wrote:
>>>
>>>  Hi all,
>>>
>>> Even if I still use EOF (due to inheritance limitations of Cayenne), I
>>> followed Hugi’s precepts :
>>> - «  use 100% java native whenever possible »
>>>
>>> One other advantage when working in a team… is that 100% java is widely
>>> documented and exampled... and it's more attractive to newbees.
>>>
>>> Sorry if I don’t « really » answer the question 😄
>>>
>>> Jérémy
>>>
>>>> Le 2 févr. 2025 à 11:13, Hugi Thordarson via Webobjects-dev
>>>> <email@hidden> a écrit :
>>>>
>>>> When I made the switch to Java collections I did do some benchmarking.
>>>> Haven’t got the code anymore (this was a decade ago) but at that time, the
>>>> Java collection classes were faster, but the operations were really so
>>>> fast in both cases that the differences were negligible — at that time.
>>>>
>>>> Since then, a decade of improvements has happened in the Java collections
>>>> so I think we can guess where you’ll find performance improvements — and
>>>> will keep getting performance improvements. On one hand you have old
>>>> classes written in an old version of Java, on the other hand you have
>>>> actively maintained open source classes used by millions of programmers
>>>> and maintained by the performance-obsessed authors of Java and the JDK
>>>> itself.
>>>>
>>>> And now for the opinion piece:
>>>> Unless you’re writing extremely performance-sensitive code — even if the
>>>> foundation collections were faster I think it makes sense to use Java
>>>> collections and write to the standard Java collection APIs where you don’t
>>>> *need* foundation collections, because If you’re using foundation specific
>>>> APIs, your code is really already obsolete at the time of writing. I never
>>>> regretted the switch and have hardly seen an NS* collection class in my
>>>> code in years, except where explicitly required as a parameter for passing
>>>> into WO APIs. (that story may be a little different if you’re using EOF
>>>> which uses the NS collections everywhere, so this may not apply in that
>>>> case).
>>>>
>>>> The Java collection classes do have their warts, the most obvious one to
>>>> us coming from the NS* world being the non-API-differentiation between
>>>> mutable and immutable collections (weird design oversight) but that hasn't
>>>> plagued me, really. It’s just something you’re aware of and don’t really
>>>> hit often.
>>>>
>>>> Another one for us WO users is that you can’t use KVC operators on Java
>>>> collections (someArray.@sortAsc, .@sum etc). When I made the switch I
>>>> always thought I’d miss these hugely and planned to write operator support
>>>> into ERXComponent’s valueForKeyPath(), but never got around to it since I
>>>> really didn’t miss the operators, preferring to keep my logic in Java
>>>> rather than templates (compile time errors and refactoring support are
>>>> awesome things).
>>>>
>>>> Probably just saying things you know — but I thought it might have some
>>>> value hearing from someone that moved to Java collections and doesn’t
>>>> regret it.
>>>>
>>>> Cheers,
>>>> - hugi
>>>>
>>>>
>>>>> On 2 Feb 2025, at 00:29, ocs--- via Webobjects-dev
>>>>> <email@hidden> wrote:
>>>>>
>>>>> Hi there,
>>>>>
>>>>> did ever anybody tried some benchmarks to find whether it is better to
>>>>> use WO collections (NSArray, NSDictionary...) as widely as possible (ie
>>>>> essentially anywhere, unless one really needs to store nulls or can't do
>>>>> without ConcurrentHashMap or so), or whether it's better to use standard
>>>>> collections (List, HashMap...) wherever they happen to work properly
>>>>> (which is surprisingly often, but not anywhere)?
>>>>>
>>>>> Are they roughly comparable, or are one or the others considerably better?
>>>>>
>>>>> Thanks!
>>>>> OC
>>>>>
>>>>> _______________________________________________
>>>>> Do not post admin requests to the list. They will be ignored.
>>>>> Webobjects-dev mailing list      (email@hidden)
>>>>> Help/Unsubscribe/Update your Subscription:
>>>>>
>>>>> This email sent to email@hidden
>>>>
>>>> _______________________________________________
>>>> Do not post admin requests to the list. They will be ignored.
>>>> Webobjects-dev mailing list      (email@hidden)
>>>> Help/Unsubscribe/Update your Subscription:
>>>>
>>>> This email sent to email@hidden
>>>
>>> _______________________________________________
>>> Do not post admin requests to the list. They will be ignored.
>>> Webobjects-dev mailing list      (email@hidden)
>>> Help/Unsubscribe/Update your Subscription:
>>>
>>> This email sent to email@hidden
>> _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Webobjects-dev mailing list      (email@hidden)
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Webobjects-dev mailing list      (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: NScollections vs Java collections
      • From: Samuel Pelletier via Webobjects-dev <email@hidden>
References: 
 >Re: NScollections vs Java collections (From: Jérémy DE ROYER via Webobjects-dev <email@hidden>)
 >Re: NScollections vs Java collections (From: Amedeo Mantica via Webobjects-dev <email@hidden>)
 >Re: NScollections vs Java collections (From: Samuel Pelletier via Webobjects-dev <email@hidden>)

  • Prev by Date: Re: NScollections vs Java collections
  • Next by Date: Re: NScollections vs Java collections
  • Previous by thread: Re: NScollections vs Java collections
  • Next by thread: Re: NScollections vs Java collections
  • Index(es):
    • Date
    • Thread