Java 7

Moderators: jkien, Xilvo

Berichten: 2.504

Java 7

http://code.joejag.com/2009/new-language-features-in-java-7/

Kwam ik tegen in m'n feeds. Een aantal nieuwe/verbeterde features in Java 7. Voor de geïnteresseerden.

Op vlak van releasedatum wordt geschreven:
The JDK currently has a release date of September 2010.
Van de voorbeelden vind ik het belangrijkst, het feit dat je nu String in switches kunt gebruiken.
"Invisible Pink Unicorns are beings of great spiritual power. We know this because they are capable of being invisible and pink at the same time. Like all religions, the Faith of the Invisible Pink Unicorns is based upon both logic and faith. We have faith that they are pink; we logically know that they are invisible because we can't see them."

Gebruikersavatar
Berichten: 4.810

Re: Java 7

Van de voorbeelden vind ik het belangrijkst, het feit dat je nu String in switches kunt gebruiken.


Imo totaal nutteloos omdat als je veel strings moet gaan vergelijken er altijd wel snellere, betere en makkelijkere methoden bestaan. Sowieso is een switch iets dat je nog zelden zou moeten gebruiken (eigenlijk zelf de laatste jaren totaal niet meer gebruikt).

Berichten: 158

Re: Java 7

Imo totaal nutteloos omdat als je veel strings moet gaan vergelijken er altijd wel snellere, betere en makkelijkere methoden bestaan. Sowieso is een switch iets dat je nog zelden zou moeten gebruiken (eigenlijk zelf de laatste jaren totaal niet meer gebruikt).
Dat is compleet onzin. Misschien heb jij de switch niet nodig gehad, maar als je actief probeert om geen switch te gebruiken (vervangen door if's of een functiepointerarray) dan ben je slecht bezig. De switch is erg handig om structuur aan te brengen in code die verschillend reageert over verschillende waarde van dezelfde variabele. Dat die 'verschillende waarde' nu ook een string kan zijn is daarom juist een verbetering.

Er is geen makkelijkere methode dan met een switch meer dan één vooraf bekende string te vergelijken. Sterker nog, het is zelfs exact even snel (afhankelijk van de onderliggende implementatie misschien zelfs sneller) dan meerdere if statements of een loop over een array van strings. De enige mogelijk snellere string vergelijkingsmethode die ik kan bedenken is met een tree en dat is absoluut niet makkelijker.
"Niet gehinderd door enige kennis van zaken..."

Gebruikersavatar
Berichten: 4.810

Re: Java 7

De enige mogelijk snellere string vergelijkingsmethode die ik kan bedenken is met een tree en dat is absoluut niet makkelijker.
Dan heb je toch maar een beperkte kennis van zaken, want laat het vergelijken van strings nu net een tak in de informatica zijn waar veel onderzoek in gebeurt is geweest en nog steeds is.

Hoe denk je dat een switch statement praktisch wordt uitgevoerd? Ja, door een if/else constructie.

Voor 2-3 strings kan het nog wel voordelig zijn (maar dan typ je evensnel een if/else structuur dan een switch). Vanaf je meerdere strings hebt kan je beter een hashmap gaan gebruiken (die geïmplementeerd worden dmv rood/zwart bomen en altijd performanter zullen zijn dan je switch). Het gebruik van een hashmap is simpel en werkt sneller dan een switch.

Op het moment dat je ook veel strings moet gaan vergelijken die je op voorhand kent en je zo'n switch constructie wil gaan gebruiken dan zit er vaak ook wat fout aan je implementatie en zal je code nauwelijks flexibel te noemen zijn.

Berichten: 158

Re: Java 7

Cycloon schreef:Dan heb je toch maar een beperkte kennis van zaken, want laat het vergelijken van strings nu net een tak in de informatica zijn waar veel onderzoek in gebeurt is geweest en nog steeds is.

...

Vanaf je meerdere strings hebt kan je beter een hashmap gaan gebruiken (die geïmplementeerd worden dmv rood/zwart bomen en altijd performanter zullen zijn dan je switch). Het gebruik van een hashmap is simpel en werkt sneller dan een switch.
Laat ik het zo zeggen: ik weet hier voldoende over om er wat zinnigs over te kunnen zeggen. En een hashmap geïmplementeerd met een boom zeg je? Dus zoals ik zei: de enige snellere manier die ik ken is d.m.v. een tree. Maar dat is niet zo makkelijk als een switch. En ja, een switch kan worden geïmplementeerd als een if/then/else-constructie en dan is het dus even snel, zoals ik ook zei. Alleen is een switch leesbaarder. En waarschijnlijk is een switch sneller omdat de compiler slechts eenmaal de waarde ophaalt en daarna steeds vergelijkt, terwijl vaak meerdere if-jes meerdere malen de waarde ophalen (afhankelijk van hoe je compiler optimaliseert).

Natuurlijk is het bij grote aantallen mogelijkheden of veranderlijke waarden niet handig een switch te gebruiken. Maar er zijn genoeg gevallen waarin het wel handig is. Vooral als de code per waarde sterk verschilt loont een switch. Iemand die een switch liever vervangt door een groot aantal if-then-else clausules heeft beperkte kennis van programmeren.

Er zijn genoeg 'bad practices' maar het gebruik van een switch is daar niet een van. Een programma dat reageert op een beperkte verzameling commando's gebruikt een switch (met strings). Een methode met een enum als argument gebruikt een switch. Veel parsers en decoders gebruiken switch-constructies.
"Niet gehinderd door enige kennis van zaken..."

Gebruikersavatar
Berichten: 5.609

Re: Java 7

Hoe denk je dat een switch statement praktisch wordt uitgevoerd? Ja, door een if/else constructie.
Bij Java heb ik geleerd NOOIT uit te gaan van hun implementatie. Ik zou bij deze dus verwonderd zijn moesten ze het zo doen.
Cycloon schreef:Voor 2-3 strings kan het nog wel voordelig zijn (maar dan typ je evensnel een if/else structuur dan een switch). Vanaf je meerdere strings hebt kan je beter een hashmap gaan gebruiken (die geïmplementeerd worden dmv rood/zwart bomen en altijd performanter zullen zijn dan je switch). Het gebruik van een hashmap is simpel en werkt sneller dan een switch.

Op het moment dat je ook veel strings moet gaan vergelijken die je op voorhand kent en je zo'n switch constructie wil gaan gebruiken dan zit er vaak ook wat fout aan je implementatie en zal je code nauwelijks flexibel te noemen zijn.
Vooreerst is snelheid tegenwoordig lang niet altijd zo belangrijk meer (en al zeker niet als je toch Java gebruikt). Hoe je die hashmap daarvoor wilt gebruiken zie ik ook niet direct, en dat op zich wil al zeggen dat het een goede verbetering is. Meestal worden die dingen nu toch al als if/else lussen ingebouwd, dus kan het enkel een verbetering zijn.
What it all comes down to, is that I haven't got it all figured out just yet

And I've got one hand in my pocket and the other one is giving the peace sign

-Alanis Morisette-

Gebruikersavatar
Berichten: 4.810

Re: Java 7

En waarschijnlijk is een switch sneller omdat de compiler slechts eenmaal de waarde ophaalt en daarna steeds vergelijkt, terwijl vaak meerdere if-jes meerdere malen de waarde ophalen (afhankelijk van hoe je compiler optimaliseert).
Java is al eeuwenlang geen volledige interpreter meer. De meeste structuren worden nu ook gecompileerd (JIT compilatie). Dat argument slaat dus op niks.
Vooral als de code per waarde sterk verschilt loont een switch. Iemand die een switch liever vervangt door een groot aantal if-then-else clausules heeft beperkte kennis van programmeren.
In welke zin zou een switch duidelijker zijn dan een if/else structuur? Zelf qua aantal regels en opmaak heeft een switch nauwelijks/geen voordeel.
Een programma dat reageert op een beperkte verzameling commando's gebruikt een switch (met strings).
Een programma die moet reageren op bepaalde commando's kan je ook weer perfect uitwerken met extra objecten die elk voor een commando staan, of wil je alle code samenproppen in je switch constructie? En het ontwerp is simpel, je maakt een interface voor je commando en je gooit al je commando objecten in een hashmap. Je programma is makkelijk uitbreidbaar en zal bij een groot aantal commando's nog steeds vlot lopen. Ok jij hebt het over een beperkte verzameling commando's, als je maar 2-3 commando's hebt lijkt het mss overkill om zoiets te gaan doen, maar als je later wil gaan uitbreiden zal je blij zijn dat er reeds een goede structuur aanwezig was.

Er zijn zelden situaties te vinden waar een switch echt voordeel oplevert. Dat de Java implementatie nu expliciet ondersteuning biedt om een string in een switch te gebruiken moedigt enkel aan om slechte manieren te programmeren, want gebruikers denken nu omdat er ondersteuning voor is dat het waarschijnlijk wel de beste oplossing is.

Gebruikersavatar
Berichten: 5.609

Re: Java 7

Wel; nu ziet iets waarbij verschillende condities binnen een string getest moeten worden er zo uit:

Code: Selecteer alles

String a = "abcdefg";

if(a.equals("a")){

   het_is_a();

}else if(a.equals("b")){

  het_is_b();

}else if(a.equals("c")){

   het_is_c();

}else{

   het_is_nog_iets_anders();

}
en dat wordt nu

Code: Selecteer alles

String a = "abcdefg";

switch(a){

case "a":

   het_is_a();

   break;

case "b":

   het_is_b();

   break;

case "c":

   het_is_c();

   break;

default:

   het_is_nog_iets_anders();

}
Ik vind het tweede veel duidelijker ogen, dus de opmaak vind ik zeker een pluspunt. Daarnaast is het nu ook simpeler om als het a is ook uit te voeren wat bij b,c en d staat, gewoon de break weglaten. Met een if-else structuur is zoiets minder duidelijk.

Overigens is jouw manier van programmeren (maak verschillende objecten aan met hetzelfde commando zodat je ze in een hashmap kunt gooien) wel bruikbaar, maar lang niet steeds het duidelijkst (en al zeker niet het leesbaarst als je tussen 10 objecten moet bladeren om naar de betekenis op zoek te gaan).
What it all comes down to, is that I haven't got it all figured out just yet

And I've got one hand in my pocket and the other one is giving the peace sign

-Alanis Morisette-

Berichten: 158

Re: Java 7

Het spijt me maar ik krijg steeds het gevoel dat je soms op iemand anders reageert dan op mij. Waar je eerst leek te reageren op een stelling dat er geen onderzoek naar het vergelijken van strings meer wordt gedaan (wie zei dat dan? ik niet dacht ik), heb je het nu ineens over een interpreter die ik niet genoemd heb.
Java is al eeuwenlang geen volledige interpreter meer. De meeste structuren worden nu ook gecompileerd (JIT compilatie). Dat argument slaat dus op niks.
Ik weet heus wel dat Java JIT gecompileerd is en dat is totaal irrelevant voor deze discussie. Mijn punt was, nogmaals: stel dat waarde 'a' (uit 317070's voorbeeld) een methodeaanroep is (zeg: geeft een random getal terug en kost 2 seconden om die te berekenen). Die compiler zal waarschijnlijk slechts eenmaal een instructie emitten waarbij de waarde van de methode wordt berekend en opgehaald, en die opgehaalde waarde dan steeds laten vergelijken in de switch. Voor meerdere if-jes is dit zeker niet het geval en wordt de methode steeds aangeroepen als deze nodig is voor de if. Dus een switch kan sneller zijn, en mijn argument slaat op deze discussie.

Over je andere argumenten: sorry maar ik verkies duidelijkheid boven het terugbrengen van het aantal regels. En dat zou elke programmeur moeten doen. Verder denk ik: veel plezier met het gebruik van een hashmap voor je 3 commando's. Waarom makkelijk doen als het moeilijk kan toch? Gebruik je nu werkelijk hashmaps voor alle stringvergelijkingen? En hoe doe je dat met de enums die ik noemde? Hoe ziet een hashmap-implementatie eruit t.o.v. hetzelfde als een switch implementatie? Hoeveel regels kost het om, in de toekomst, één commando aan je hashmap toe te voegen, en hoeveel kost het om datzelfde aan een switch toe te voegen?

Bij een switch zijn alle 'keys' (mogelijke waarden) van te voren bekend. Als je hier een hashmap van maakt moet je dus een perfecte hash functie hebben om in de slechtst mogelijke situatie snel genoeg te zijn. Hoe krijg jij in Java zo'n functie ingesteld?

Een Hashmap is bijvoorbeeld ingesteld op een maximale load van 0.7. Oftewel, het kost 21% van het geheugengebruik van een switch extra door een hashmap te gebruiken (zonder overhead).

Enne... in een switch kan je de geprefereerde keus hoger in de lijst zetten. En je kan de rest afvangen met een 'default' clausule. Knappe kop die beide met een hashmap voor mekaar krijgt, nietwaar?

Trouwens, is 317070's voorbeeld niet veel duidelijker? Vooral als je je voorstelt dat 'a' mogelijk een lange expressie zou kunnen zijn.
"Niet gehinderd door enige kennis van zaken..."

Gebruikersavatar
Berichten: 4.810

Re: Java 7

virtlink schreef:Bij een switch zijn alle 'keys' (mogelijke waarden) van te voren bekend. Als je hier een hashmap van maakt moet je dus een perfecte hash functie hebben om in de slechtst mogelijke situatie snel genoeg te zijn. Hoe krijg jij in Java zo'n functie ingesteld?

Een Hashmap is bijvoorbeeld ingesteld op een maximale load van 0.7. Oftewel, het kost 21% van het geheugengebruik van een switch extra door een hashmap te gebruiken (zonder overhead).

Enne... in een switch kan je de geprefereerde keus hoger in de lijst zetten. En je kan de rest afvangen met een 'default' clausule. Knappe kop die beide met een hashmap voor mekaar krijgt, nietwaar?
Hash functies zijn geamortiseerd altijd sneller dan een sequentiële doorloop van een switch constructie, zelf indien de sleutels vooraf niet bekend zijn kan je wiskundig bewijzen dat een familie van hashfuncties er voor zorgt dat de gemiddelde performantie beter zal zijn dan O(n).

De "rest" afvangen met een defaultwaarde is nauwelijks moeilijker, je hoeft enkel te controleren of een bepaalde sleutel aanwezig is. In een switch zal de defaultwaarde altijd pas na n vergelijkingen kunnen vastgesteld worden, bij een hashmap kan dit zelf vaak met slechts 1 vergelijking.

Mocht een hashmap dan toch in sommige gevallen slecht uitvallen dan kunnen we nog steeds een treemap gaan gebruiken die dmv rood/zwart-boom implementatie altijd een performantie haalt van O(lg n). Daar zit je dan te kijken met je O(n) constructie :eusa_whistle:

Nuja, ik heb nogal het gevoel dat jullie liever straightforward code zitten te kloppen die nauwelijks flexibel en efficiënt is. De implementatie die ik aandraag vraagt idd iets meer tijd om te implementeren, maar is in alle gevallen duidelijker en beter onderhoudbaar. Ik blijf bij mijn standpunt dat van zodra je meer dan 3 if testen nodig hebt (of 3 staten in je switchen) de geschreven code een andere structuur vraagt. Door de verdere support van switches heb ik nogal het gevoel dat slecht gestructuurde code wordt aangemoedigd.

Hopelijk moet ik nooit code onderhouden die door jullie geschreven is ](*,)

Gebruikersavatar
Berichten: 6.905

Re: Java 7

Ik blijf bij mijn standpunt dat van zodra je meer dan 3 if testen nodig hebt (of 3 staten in je switchen) de geschreven code een andere structuur vraagt. Door de verdere support van switches heb ik nogal het gevoel dat slecht gestructuurde code wordt aangemoedigd.
Kan je dit, eventueel met wat voorbeelden, beter uitleggen? Heb je het nu over structuur, of ook over optimalisatie en dergelijk?
Het vel van de beer kunnen verkopen vraagt moeite tenzij deze dood voor je neervalt. Die kans is echter klein dus moeten we zelf moeite doen.

Berichten: 202

Re: Java 7

Beetje offtopic hierzo, kun je beter afsplitsen..

En verder een niet zo bijzondere blog, enige wat hij bespreekt is een de syntax die wat veranderd.

Lijkt me veel interessanter om te zien wat er in de JVM verandert.

Gebruikersavatar
Berichten: 691

Re: Java 7

In pascal kun je ook dit doen:

t:='A'

repeat;

if t='A' then begin oproep;break; endif

if t='B' then begin oproep;break; endif

if t='C' then begin oproep;break; endif

if t='D' then begin oproep;break; endif

until true;

staat beter dan nesten met else en voorkomt stacking

En ook if functieoproep()=t blijft toepasbaar en dat heeft men met case niet.

Bij een goede compiler is case sneller omdat dit geoptimaliseerd wordt, maar men zit vast aan een vaste constructie van constanten.

Er is geen functie oproep mogelijk en complexe testen zijn ook niet toepasbaar.

Dus het een en ander is afhankelijk van de situatie.
Een computertaal is voor mensen, niet voor de computer.

Berichten: 99

Re: Java 7

Hash functies zijn geamortiseerd...
Geamortiseerd, wat is dat?

Gebruikersavatar
Berichten: 4.810

Re: Java 7

Geamortiseerd, wat is dat?
Om even een vrij simpel voorbeeld te nemen:

Een vector wordt in het geheugen gereserveerd als een tabel van een bepaalde grootte (voor het gemak nemen we even 10 groot). Wanneer je elementen in de vector steekt gaat dit even snel als bij een gewone tabel, namelijk O(1). Wanneer je echter een elfde element op de vector probeert te steken moet er een grotere tabel gemaakt worden en moet je alle elementen kopiëren naar de nieuwe tabel, dit is maar O(n). Als je echt alles uitmiddelt over de 11 elementen krijg je iets in de ordegrootte van O(2) performantie voor het geheel. We kunnen dus zeggen dat de geamortiseerde performantie van een vector O(1) blijft.

Nu bij hashes heb je een gelijkaardige situatie. In sommige gevallen zullen er meerdere elementen per hashentry zitten. Je zou er van kunnen uitgaan dat alle elementen in dezelfde hashingang komen en dan zou opzoeken O(n) zijn (namelijk gewoon sequentieel doorlopen). Maar dan zouden alle andere op te zoeken strings slechts O(1) zijn (vermits daar geen entries meer zijn). Als we dit nu weer uitmiddelen krijg je een geamortiseerde zoeksnelheid van O(1).

Hopelijk kan je een beetje volgen? :eusa_whistle:

Reageer