<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Java - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Impara a programmare gratuitamente! Tutorial di programmazione su Python, JavaScript, Linux e molto altro. ]]>
        </description>
        <link>https://www.freecodecamp.org/italian/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Java - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/italian/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Thu, 14 May 2026 04:08:30 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/italian/news/tag/java/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Le Interfacce in Java Spiegate con Esempi ]]>
                </title>
                <description>
                    <![CDATA[ Un'interfaccia in Java è un po' come una classe, ma con una differenza significativa: una interface può avere solo le firme dei metodi, attributi e metodi di default. A partire da Java 8, puoi anche creare metodi di default [https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html]. Nel prossimo blocco di codice puoi vedere un esempio di ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/le-interfacce-in-java-spiegate-con-esempi/</link>
                <guid isPermaLink="false">6547ee47e253cc03fcab8814</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paola Rosati ]]>
                </dc:creator>
                <pubDate>Wed, 21 Feb 2024 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/12/5f9c9ce6740569d1a4ca34c5.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/java-interfaces-explained-with-examples/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Java Interfaces Explained with Examples</a>
      </p><p>Un'interfaccia in Java è un po' come una classe, ma con una differenza significativa: una <code>interface</code> può avere <em>solo </em>le firme dei metodi, attributi e metodi di default<em>. </em>A partire da Java 8, puoi anche creare <a href="https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html">metodi di default</a>. Nel prossimo blocco di codice puoi vedere un esempio di interfaccia:</p><pre><code class="language-java">public interface Veicolo {
    public String targa = "";
    public float maxVel;
    public void accendi();
    public void spegni();
    default void suonaClacson(){
      System.out.println("Sto suonando il clacson");
   }
}</code></pre><p>L'interfaccia qui in alto contiene due attributi, due metodi e un metodo di default. Da sola, non è molto utile, ma di solito vengono usate insieme alle Classi. In che modo? Semplice, devi assicurarti che delle classi la implementino, usando la parola chiave <code>implements</code>.</p><pre><code class="language-java">public class Macchina implements Veicolo {
    public void accendi() {
        System.out.println("avvio del motore...");
    }
    public void spegni() {
        System.out.println("spegnendo il motore...");
    }
}</code></pre><p>Ora, c'è una <strong>regola di base</strong>: la classe deve implementare <strong>tutti </strong>i metodi dell'interfaccia. I metodi devono avere <em>la stessa identica</em> firma (nome, parametri ed eccezioni) così com'è descritta nell'interfaccia. La classe, però, <em>non</em> ha bisogno di dichiarare gli attributi, solo i metodi.</p><h2 id="istanze-di-un-interfaccia"><strong><strong>Istanze di un'Interfaccia</strong></strong></h2><p>Una volta creata una classe di Java che implementa una qualsiasi Interfaccia, l'istanza dell'oggetto deve essere referenziata come istanza dell'interfaccia. Questo concetto è simile a quello dell'istanziazione ereditaria.</p><pre><code class="language-java">// facendo seguito al nostro esempio di prima

Veicolo tesla = new Macchina();

tesla.parti(); // avvio del motore ...</code></pre><p>Un'interfaccia <strong>non può</strong> contenere un costruttore. Per questo, <strong>non puoi</strong> creare un'istanza dell'interfaccia stessa. Devi creare un'istanza di una classe implementando un'interfaccia per poterla referenziare.</p><p>Pensa alle interfacce come a moduli di contratto vuoti, o come template.</p><p>Che cosa puoi fare con questa funzionalità? Polimorfismo! Puoi usare solo le interfacce per riferirti alle istanze dell'oggetto!</p><pre><code class="language-java">class Camion implements Veicolo {
    public void avvio() {
        System.out.println("avvio del motore del camion...");
    }
    public void spegni() {
        System.out.println("spegnimento del motore del camion...");
    }
}

class Starter {
    // metodo statico, può essere invocato senza istanziare la classe
    public static void avviaMotore(Veicolo veicolo) {
        veicolo.avvio();
    }
}

Veicolo tesla = new Macchina();
Veicolo tata = new Camion();

Starter.avviaMotore(tesla); // avvio del motore ...
Starter.avviaMotore(tata); // avvio del motore del camion ...</code></pre><h2 id="e-per-quanto-riguarda-molteplici-interfacce"><strong>E per quanto riguarda molteplici interfacce?</strong></h2><p>Sì, puoi implementare molteplici interfacce in una sola classe. Mentre nell'<a href="https://forum.freecodecamp.com/t/java-docs-inheritance">ereditarietà</a> tra classi sei costretto ad ereditare da una sola classe, qui puoi estendere un numero qualsiasi di interfacce. Ma non dimenticare di implementare <em>tutti</em> i metodi di tutte le Interfacce, altrimenti la compilazione fallirà!</p><pre><code class="language-java">public interface GPS {
    public void ottieniCoordinate();
}

public interface Radio {
    public void accendiRadio();
    public void spegniRadio();
}

public class Smartphone implements GPS,Radio {
    public void ottieniCoordinate() {
        // return delle coordinate
    }
    public void accendiRadio() {
      // accendi Radio
    }
    public void spegniRadio() {
        // spegni Radio
    }
}</code></pre><h2 id="alcune-caratteristiche-delle-interfacce"><strong>Alcune caratteristiche delle Interfacce</strong></h2><ul><li>Puoi inserire delle variabili all'interno di un'Interfaccia, anche se non sarebbe una decisione sensata poiché le Classi non sono tenute ad avere la stessa variabile. In breve, evita di inserire delle variabili!</li><li>Tutte le variabili e i metodi in un'Interfaccia sono pubblici, anche se non metti la parola chiave <code>public</code>.</li><li>Un'Interfaccia non può specificare l'implementazione di un metodo in particolare. Sta alle Classi farlo. Anche se c'è stata una recente eccezione (vedi più avanti).</li><li>Se una Classe implementa più Interfacce, allora c'è una remota possibilità che la firma di un metodo coincida con un'altra. Poiché Java non permette di avere più metodi con la stessa firma, questo può causare problemi. Dai un'occhiata a <a href="http://stackoverflow.com/questions/2598009/method-name-collision-in-interface-implementation-java">questa domanda</a> per maggiori informazioni.</li></ul><h2 id="metodi-di-default-delle-interfacce"><strong>Metodi di Default delle Interfacce</strong></h2><p>Prima di Java 8, non c'era nessun modo per far sì che un'interfaccia avesse una specifica implementazione di un metodo. Questo porta ad un sacco di confusione ed errori di codice nel caso in cui la definizione di un'interfaccia venga cambiata.</p><p>Ipotizza di aver scritto una libreria open source, che contiene un'Interfaccia. Supponiamo che i tuoi clienti, ovvero praticamente tutti gli sviluppatori del mondo, ne stiano facendo ampio uso e siano felici. Adesso hai dovuto aggiornare la libreria aggiungendo una nuova definizione di un metodo dell'Interfaccia per supportare una nuova funzionalità. Ma questo romperebbe <em>tutti</em> i build, poiché tutte le Classi che implementano quell'Interfaccia devono essere cambiate. Che catastrofe!</p><p>Fortunatamente, Java 8 adesso ci mette a disposizione dei metodi <code>default</code> per le Interfacce. Un metodo <code>default</code> <em>può</em> contenere una sua implementazione direttamente all'interno dell'Interfaccia. Dunque, se una Classe non implementa il metodo di default, il compilatore prenderà l'implementazione menzionata nell'Interfaccia. Comodo, vero? Dunque, nella tua libreria, potrai aggiungere qualsiasi numero di metodi di default nelle interfacce senza temere di rompere nulla!</p><pre><code class="language-java">public interface GPS {
    public void ottieniCoordinate();
    default public void ottieniCoordinateApprossimative() {
        // implementazione per restituire coordinate da fonti approssimative
        // come il wifi o il telefono
        System.out.println("Prendo coordinate approssimative...");
    }
}

public interface Radio {
    public void accendiRadio();
    public void spegniRadio();
}

public class Smartphone implements GPS,Radio {
    public void ottieniCoordinate() {
        // return delle coordinate
    }
    public void accendiRadio() {
      // accendi Radio
    }
    public void spegniRadio() {
        // spegni Radio
    }

    // nessuna implementazione per ottieniCoordinateApprossimative()
}

Smartphone motoG = new Smartphone();
motog.ottieniCoordinateApprossimative(); // Prendo coordinate approssimative...</code></pre><p><strong>Ma cosa succede se due interfacce hanno la stessa firma di un metodo?</strong></p><p>Ottima domanda. In quel caso, se non fornisci un'implementazione all'interno della Classe, il povero compilatore si confonderà e, semplicemente, fallirà! Devi fornire un'implementazione di metodo di default anche all'interno della Classe. C'è anche un modo elegante di farlo usando <code>super</code> per chiamare l'implementazione che preferisci: </p><pre><code class="language-java">public interface Radio {
    // public void accendiRadio();
    // public void spegniRadio();

    default public void prossima() {
        System.out.println("Prossima canzone dalla Radio");
    }
}

public interface LettoreMusicale {
    // public void accendi();
    // public void pausa();
    // public void spegni();

    default public void prossima() {
        System.out.println("Prossima canzone dal lettore musicale");
    }
}

public class Smartphone implements Radio, LettoreMusicale {
    public void prossima() {
        // Supponiamo che tu voglia chiamare prossima() del LettoreMusicale
        LettoreMusicale.super.prossima();
    }
}

Smartphone motoG = new Smartphone();
motoG.prossima(); // Prossima canzone dal lettore musicale</code></pre><h2 id="metodi-statici-nelle-interfacce"><strong>Metodi Statici nelle Interfacce</strong></h2><p>Un'altra novità in Java 8 è la possibilità di aggiungere metodi statici alle interfacce. I metodi statici delle interfacce sono quasi identici ai metodi statici delle classi concrete. L'unica grande differenza è che i metodi <code>static</code> non sono ereditati nelle classi che implementano l'interfaccia. Ciò significa che quando si chiama il metodo statico viene referenziata l'interfaccia, non la classe che lo implementa.</p><pre><code class="language-java">interface LettoreMusicale {
  public static void spotPubblicitario(String sponsor) {
    System.out.println("Adesso una promozione da " + sponsor);
  }
  
  public void riproduci();
}


class Smartphone implements LettoreMusicale {
	public void riproduci() {
		System.out.println("Riproduco da smartphone");
	}
}

class Main {
  public static void main(String[] args) {
    Smartphone motoG = new Smartphone();
    MusicPlayer.spotPubblicitario("Motorola"); // Chiamato dall'interfaccia, non dalla classe che la implementa
    // motoG.spotPubblicitario("Motorola"); // Questo causerebbe un errore di compilazione
  }
}</code></pre><h2 id="ereditariet-nelle-interfacce"><strong>Ereditarietà nelle interfacce</strong></h2><p>È inoltre possibile, in Java, che un'interfaccia <em>erediti</em> un'altra interfaccia usando, come hai già immaginato, la parola chiave <code>extends</code>:</p><pre><code class="language-java">public interface Lettore {
    public void accendi();
    public void pausa();
    public void spegni();
}

public interface LettoreMusicale extends Lettore {
    default public void prossima() {
        System.out.println("Prossima canzone dal lettore musicale");
    }
}</code></pre><p>Ciò significa che la Classe che implementa l'Interfaccia <code>LettoreMusicale</code> deve implementare <em>tutti </em>i metodi di <code>LettoreMusicale</code> così come quelli di <code>Lettore</code>:</p><pre><code class="language-java">public class SmartPhone implements LettoreMusicale {
    public void accendi() {
        System.out.println("Accensione");
    }
    public void spegni() {
        System.out.println("Spegnimento");
    }
    public void pausa() {
        System.out.println("Messo in pausa");
    }
}</code></pre><p>Adesso hai una visione più chiara delle interfacce di Java! Dai un'occhiata alle Classi Astratte per vedere un altro modo in cui Java ti permette di definire contratti.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Da Stringa ad Array di Caratteri - Tutorial Java ]]>
                </title>
                <description>
                    <![CDATA[ In questo articolo vedremo come convertire una stringa in un array di caratteri in Java. Ti spiegherò brevemente anche che cosa sono le stringhe, i caratteri e gli array. Che Cos'è un Carattere in Java? I caratteri sono tipi di dato primitivi. Un carattere è un singolo carattere racchiuso tra ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/da-stringa-ad-array-di-caratteri-tutorial-java/</link>
                <guid isPermaLink="false">64f34cbe21109103fd7baab7</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paola Rosati ]]>
                </dc:creator>
                <pubDate>Tue, 26 Sep 2023 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/09/k.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/string-to-char-array-java-tutorial/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">String to Char Array Java Tutorial</a>
      </p><p>In questo articolo vedremo come convertire una stringa in un array di caratteri in Java. Ti spiegherò brevemente anche che cosa sono le stringhe, i caratteri e gli array.</p><h2 id="che-cos-un-carattere-in-java"><strong>Che Cos'è un Carattere in Java?</strong></h2><p>I caratteri sono tipi di dato primitivi. Un carattere è un singolo carattere racchiuso tra due apici singoli. Può essere una lettera, un numero, un segno di punteggiatura, uno spazio o qualcosa di simile. Per esempio:</p><pre><code class="language-java">char primaVocale = 'a';</code></pre><h2 id="che-cos-una-stringa-in-java"><strong>Che Cos'è una Stringa in Java?</strong></h2><p>Le stringhe sono oggetti (tipo di riferimento). Una stringa è composta da una serie di caratteri. È qualsiasi cosa che si trova tra le doppie virgolette. Per esempio:</p><pre><code class="language-java">String vocali = "aeiou";</code></pre><h2 id="che-cos-un-array-in-java"><strong>Che Cos'è un Array in Java?</strong></h2><p>Gli array sono strutture di dati fondamentali che in Java possono immagazzinare un determinato numero di elementi dello stesso tipo di dato. Per esempio, dichiariamo un array di caratteri:</p><pre><code class="language-java">char[] arrayVocali = {'a', 'e', 'i', 'o', 'u'};</code></pre><p>Ora abbiamo una conoscenza di base di quello che sono stringhe, caratteri e array.</p><h2 id="convertiamo-una-stringa-in-un-array-di-caratteri"><strong>Convertiamo una Stringa in un Array di Caratteri</strong></h2><h3 id="1-usa-il-metodo-di-istanza-tochararray-"><strong>1. Usa il Metodo di Istanza toCharArray()</strong></h3><p><code>toCharArray()</code> è un metodo d'istanza della classe <code>String</code>. Restituisce un nuovo array di caratteri basato sull'oggetto stringa corrente.</p><p>Vediamo un esempio:</p><pre><code class="language-java">// definisci una stringa
String vocali = "aeiou";

// crea un array di caratteri 
char[] arrayVocali = vocali.toCharArray();

// stampa arrayVocali
System.out.println(Arrays.toString(arrayVocali));</code></pre><p>Output: <code>[a, e, i, o, u]</code></p><p>Quando convertiamo una stringa in un array di caratteri, la lunghezza rimane la stessa. Controlliamo la lunghezza di <code>vocali</code> e di <code>arrayVocali</code>:</p><pre><code class="language-java">System.out.println("La lunghezza di \'vocali\' è " + vocali.length());
System.out.println("La lunghezza di \'arrayVocali\' è " + arrayVocali.length);</code></pre><p>Output:</p><pre><code>La lunghezza di 'vocali' è 5
La lunghezza di 'arrayVocali' è 5</code></pre><p>Possiamo usare diversi modi di stampare un array. Ho usato il metodo statico <code>toString()</code> dalla classe di utilità <code>Arrays</code>.</p><p>Puoi leggere di più riguardo il metodo d'istanza <code>toCharArray()</code> nella <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#toCharArray--">documentazione di Java</a>.</p><h3 id="2-usa-il-metodo-di-istanza-charat-"><strong>2. Usa il Metodo di Istanza charAt()</strong></h3><p><code>charAt()</code> è un metodo d'istanza della classe <code>String</code>. Restituisce il carattere che si trova all'indice specificato della stringa corrente.</p><p><strong><strong>NOT</strong>A<strong>:</strong></strong> una stringa ha indici che partono da zero, come un array.</p><p>Vediamo come possiamo convertire una stringa in un array di caratteri usando <code>charAt()</code> :</p><pre><code class="language-java">// definisci una stringa
String vocali = "aeiou";

// crea un array di caratteri. La lunghezza è la lunghezza di 'vocali'
char[] arrayVocali = new char[vocali.length()];

// usa un ciclo per iterare attraverso ogni carattere nella stringa 'vocali'
for (int i = 0; i &lt; vocali.length(); i++) {
    // aggiungi ogni carattere all'array di caratteri
    arrayVocali[i] = vocali.charAt(i);
}

// stampa l'array
System.out.println(Arrays.toString(arrayVocali));</code></pre><p>Output: <code>[a, e, i, o, u]</code></p><p>Puoi leggere di più riguardo il metodo d'istanza <code>charAt()</code> nella <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#charAt-int-">documentazione di Java</a>.</p><p>Ti ho appena mostrato un altro modo di convertire una stringa in un array di caratteri, ma possiamo usare il metodo <code>toCharArray()</code> per convertirla facilmente invece di creare un loop e iterare attraverso la stringa.</p><p>Sentiti libero di farmi sapere se hai suggerimenti o domande.</p><p>Foto di <a href="https://unsplash.com/@a2_foto?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Alex Alvarez</a> su <a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>.</p><p><strong>Supporta<strong> freeCodeCamp </strong>nella loro <a href="https://www.freecodecamp.org/italian/news/stiamo-realizzando-un-curriculum-in-data-science-con-matematica-avanzata-e-machine-learning/">Raccolta Fondi del Curriculum di Scienza dei Dati</a><strong>.</strong></strong></p><p>Mettiti in contatto con me su <a href="https://mvthanoshan.medium.com/">Medium</a>.</p><p>Grazie 😇</p><p><strong>Buona Programmazione<strong><strong><strong><strong><strong><strong><strong> ❤️</strong></strong></strong></strong></strong></strong></strong></strong></p><h3 id="per-saperne-di-pi-sulla-programmazione-in-java"><strong>Per saperne di più sulla Programmazione<strong><strong> in Java</strong></strong></strong></h3><ol><li><a href="https://www.freecodecamp.org/news/java-object-oriented-programming-system-principles-oops-concepts-for-beginners/">Principi di Programmazione Orientata agli Oggetti in Java: Concetti OOP per Principianti</a></li><li><a href="https://www.freecodecamp.org/italian/news/metodi-per-array-in-java-come-stampare-un-array-in-java/">Metodi degli Array in Java - Come Stampare un Array in Java</a></li><li><a href="https://www.freecodecamp.org/news/java-string-to-int-how-to-convert-a-string-to-an-integer/">Da Stringa a Int in Java - Come Convertire una Stringa in un Numero Intero</a></li><li><a href="https://www.freecodecamp.org/italian/news/generatore-di-numeri-casuali-in-java-come-generare-interi-con-math-random/">Generatore di Numeri Casuali in Java - Come Generare Numeri Interi con Math Random</a></li></ol> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Metodi per Array in Java – Come Stampare un Array in Java ]]>
                </title>
                <description>
                    <![CDATA[ Un array è una struttura di dati usata per immagazzinare dati dello stesso tipo. Gli array immagazzinano i propri elementi in posizioni di memoria contigue. In Java, gli array sono oggetti. Tutti i metodi della classe object possono essere chiamati su un array. Possiamo immagazzinare un numero fisso di elementi ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/metodi-per-array-in-java-come-stampare-un-array-in-java/</link>
                <guid isPermaLink="false">64f590b508035e03fe8ca1de</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paola Rosati ]]>
                </dc:creator>
                <pubDate>Mon, 25 Sep 2023 08:48:13 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/09/Untitled-design--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/java-array-methods-how-to-print-an-array-in-java/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Java Array Methods – How to Print an Array in Java</a>
      </p><p>Un array è una struttura di dati usata per immagazzinare dati dello stesso tipo. Gli array immagazzinano i propri elementi in posizioni di memoria contigue.</p><p>In Java, gli array sono oggetti. Tutti i metodi della classe object possono essere chiamati su un array. Possiamo immagazzinare un numero fisso di elementi in un array.</p><p>Dichiariamo un semplice array di tipo primitivo:</p><pre><code class="language-java">int[] intArray = {2,5,46,12,34};</code></pre><p>Adesso proviamo a stamparlo usando il metodo <code>System.out.println()</code>:</p><pre><code class="language-java">System.out.println(intArray);
// output: [I@74a14482</code></pre><p>Perché Java non ha stampato il nostro array? Che cosa sta succedendo dietro le quinte?</p><p>Il metodo <code>System.out.println()</code> converte l'oggetto che abbiamo passato in una stringa chiamando <code>String.valueOf()</code>. Se diamo un'occhiata all'implementazione del metodo <code>String.valueOf()</code> vedremo questo:</p><pre><code class="language-java">public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}</code></pre><p>Se l'oggetto passato è <code>null</code> ci restituisce null, altrimenti chiama il metodo <code>obj.toString()</code> . Alla fine, <code>System.out.println()</code> chiama <code>toString()</code> per stampare l'output.</p><p>Se la classe di quell'oggetto non sovrascrive l'implementazione di <code>Object.toString()</code>, chiamerà il metodo <code>Object.toString()</code>.</p><p><code>Object.toString()</code> restituisce <code>getClass().getName()+<strong><strong><strong><strong>‘@’</strong></strong></strong></strong>+Integer.toHexString(hashCode())</code> . In parole povere, restituisce: "nome della classe @ codice hash dell'oggetto".</p><p>Nel nostro precedente output <code>[I@74a14482</code> , <code>[</code> esprime che si tratta di un array, e <code>I</code> sta per int (il tipo dell'array). <code>74a14482</code> è la rappresentazione esadecimale senza segno del codice hash dell'array.</p><p>Ogni volta che creiamo le nostre classi personalizzate, è buona prassi sovrascrivere il metodo <code>Object.toString()</code>.</p><p>Non possiamo stampare gli array in Java usando il banale metodo <code>System.out.println()</code>. Invece, questi sono i modi in cui possiamo stampare un array:</p><ol><li>Loop: loop for e loop for-each</li><li>Il metodo <code>Arrays.toString()</code></li><li>Il metodo <code>Arrays.deepToString()</code></li><li>Il metodo <code>Arrays.asList()</code></li><li>L'interfaccia Java Iterator</li><li>Java Stream API</li></ol><p>Vediamoli uno ad uno.</p><h1 id="1-loop-loop-for-e-loop-for-each"><strong>1. </strong>Loop: loop for e loop for-each</h1><p>Ecco un esempio di un loop for:</p><pre><code class="language-java">int[] intArray = {2,5,46,12,34};

for(int i=0; i&lt;intArray.length; i++){
    System.out.print(intArray[i]);
    // output: 25461234
}</code></pre><p>Tutte le classi wrapper sovrascrivono <code>Object.toString()</code> e restituiscono una rappresentazione del loro valore in formato di stringa.</p><p>Ed ecco un loop for-each:</p><pre><code class="language-java">int[] intArray = {2,5,46,12,34};

for(int i: intArray){
    System.out.print(i);
    // output: 25461234
}</code></pre><h1 id="2-il-metodo-arrays-tostring-"><strong>2. Il metodo Arrays.toString()</strong></h1><p><code>Arrays.toString()</code> è un metodo statico della classe array che appartiene al package <code>java.util</code>. Restituisce una rappresentazione dei contenuti dell'array specificato in formato di stringa. Possiamo stampare array unidimensionali usando questo metodo.</p><p>Gli elementi dell'array sono convertiti in stringhe usando il metodo <code>String.valueOf()</code>, in questo modo:</p><pre><code class="language-java">int[] intArray = {2,5,46,12,34};
System.out.println(Arrays.toString(intArray));
// output: [2, 5, 46, 12, 34]</code></pre><p>Per un array di riferimenti, dobbiamo assicurarci che la classe del tipo di riferimento sovrascriva il metodo <code>Object.toString()</code>.</p><p>Per esempio:</p><pre><code class="language-java">public class Test {
    public static void main(String[] args) {
        Studente[] studenti = {new Studente("John"), new Studente("Doe")};
        
        System.out.println(Arrays.toString(studenti));
        // output: [Studente{nome='John'}, Studente{nome='Doe'}]
    }
}

class Studente {
    private String nome;

    public Student(String nome){
        this.nome = nome;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    @Override
    public String toString() {
        return "Studente{" + "nome='" + nome + '\'' + '}';
    }
}</code></pre><p>Questo metodo non è appropriato per array multidimensionali. Converte gli array multidimensionali in stringhe usando <code>Object.toString()</code> che descrive i loro id al posto dei loro contenuti.</p><p>Per esempio:</p><pre><code class="language-java">// creo un array multidimensionale
int[][] multiDimensionalArr = { {2,3}, {5,9} };

System.out.println(Arrays.toString(multiDimensionalArr));
// output: [[I@74a14482, [I@1540e19d]</code></pre><p>Con l'aiuto di <code>Arrays.deepToString()</code>, possiamo stampare array multidimensionali.</p><h1 id="3-il-metodo-arrays-deeptostring-"><strong>3. Il metodo Arrays.deepToString()</strong></h1><p><code>Arrays.deepToString()</code> restituisce una rappresentazione dei "contenuti profondi" dell'array specificato in formato di stringa.</p><p>Se l'elemento è un array di tipo primitivo, viene convertito in una stringa chiamando il sovraccarico appropriato di <code>Arrays.toString()</code> .</p><p>Ecco un esempio di un array multidimensionale di tipo primitivo:</p><pre><code class="language-java">// creo un array multidimensionale
int[][] multiDimensionalArr = { {2,3}, {5,9} };

System.out.println(Arrays.deepToString(multiDimensionalArr));
// output: [[2, 3], [5, 9]]</code></pre><p>Se l'elemento è un array di riferimenti, viene convertito in una stringa chiamando ricorsivamente <code>Arrays.deepToString()</code>.</p><pre><code class="language-java">Insegnante[][] insegnanti = 
{{ new Insegnante("John"), new Insegnante("David") }, {new Insegnante("Mary")} };

System.out.println(Arrays.deepToString(insegnanti));
// output: 
[[Insegnante{nome='John'}, Insegnante{nome='David'}],[Insegnante{nome='Mary'}]]</code></pre><p>Dobbiamo sovrascrivere <code>Object.toString()</code> nella nostra classe Insegnante.</p><p>Se ti incuriosisce il modo in cui viene eseguita la ricorsione, ecco il <a href="http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/be44bff34df4/src/share/classes/java/util/Arrays.java#l4611">codice sorgente</a> del metodo <code>Arrays.deepToString()</code>.</p><p><strong><strong><strong><strong>NOT</strong></strong></strong>A<strong><strong><strong>:</strong></strong></strong></strong> anche gli array unidimensionali di riferimenti possono essere stampati usando questo metodo. Per esempio:</p><pre><code class="language-java">Integer[] oneDimensionalArr = {1,4,7};

System.out.println(Arrays.deepToString(oneDimensionalArr));
// output: [1, 4, 7]</code></pre><h1 id="4-il-metodo-arrays-aslist-"><strong>4. Il metodo Arrays.asList()</strong></h1><p>Questo metodo restituisce una lista di dimensioni fisse costruita sull'array specificato.</p><pre><code class="language-java">Integer[] intArray = {2,5,46,12,34};

System.out.println(Arrays.asList(intArray));
// output: [2, 5, 46, 12, 34]</code></pre><p>Abbiamo cambiato il tipo da int a Integer, perché List è un insieme che contiene una lista di oggetti. Quando convertiamo un array in una lista dovrebbe essere un array di riferimenti.</p><p>Java chiama <code>Arrays.<em><em><em><em>asList</em></em></em></em>(intArray).toString()</code> . Questa tecnica usa internamente il metodo <code>toString()</code> del tipo degli elementi all'interno della lista.</p><p>Un altro esempio con la nostra classe personalizzata Insegnante:</p><pre><code class="language-java">Insegnante[] insegnante = { new Insegnante("John"), new Insegnante("Mary") };

System.out.println(Arrays.asList(insegnante));
// output: [Insegnante{nome='John'}, Insegnante{nome='Mary'}]</code></pre><p><strong><strong>NOT</strong>A<strong>:</strong></strong> non possiamo stampare array multidimensionali usando questo metodo. Per esempio:</p><pre><code class="language-java">Insegnante[][] insegnanti = 
{{ new Insegnante("John"), new Insegnante("David") }, { new Insegnante("Mary") }};
        
System.out.println(Arrays.asList(insegnanti));

// output: [[Lcom.thano.article.printarray.Insegnante;@1540e19d, [Lcom.thano.article.printarray.Insegnante;@677327b6]</code></pre><h1 id="5-l-interfaccia-java-iterator"><strong>5. L'interfaccia Java Iterator</strong></h1><p>In modo simile a un loop for-each, possiamo usare l'interfaccia Iterator per iterare attraverso gli elementi dell'array e stamparli.</p><p>L'oggetto Iterator può essere creato chiamando il metodo <code>iterator()</code> su una Collection. Quell'oggetto verrà usato per iterare attraverso gli elementi della Collection.</p><p>Ecco un esempio di come possiamo stampare un array usando l'interfaccia Iterator:</p><pre><code class="language-java">Integer[] intArray = {2,5,46,12,34};

// creo una List di Integer
List&lt;Integer&gt; list = Arrays.asList(intArray);

// creo un iteratore della Integer List
Iterator&lt;Integer&gt; it = list.iterator();

// se la List ha elementi da iterare
while(it.hasNext()) {
    System.out.print(it.next());
    // output: 25461234
}</code></pre><h1 id="6-java-stream-api"><strong>6. Java Stream API</strong></h1><p>La Stream API è usata per lavorare con insiemi di oggetti. Uno stream è una sequenza di oggetti. Gli stream non cambiano la struttura dei dati originaria, forniscono soltanto il risultato delle operazioni richieste.</p><p>Con l'aiuto dell'operazione terminale <code>forEach()</code> possiamo iterare attraverso ogni elemento dello stream.</p><p>Per esempio:</p><pre><code class="language-java">Integer[] intArray = {2,5,46,12,34};

Arrays.stream(intArray).forEach(System.out::print);
// output: 25461234</code></pre><p>Adesso sappiamo come stampare un array in Java.</p><p>Grazie per aver letto.</p><p>Immagine di copertina di <a href="https://unsplash.com/@acharki95?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Aziz Acharki</a> su <a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>.</p><p>Puoi leggere gli altri miei articoli su <a href="https://medium.com/@mvthanoshan9/object-oriented-programming-principles-in-java-820919dced1a">Medium</a>.</p><p><strong>Buona Programmazione<strong><strong><strong>!</strong></strong></strong></strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Come Eseguire il Codice Java dal Terminale ]]>
                </title>
                <description>
                    <![CDATA[ Se lavori con Java, probabilmente hai usato uno dei più famosi editor di testo come Sublime Text, VS Code, Brackets, Atom, e Notepad++, o anche IDE come Apache NetBeans e IntelliJ IDEA. Eseguire il codice nel tuo IDE è immediato, ma spesso non riesci a vedere in che modo viene ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/come-eseguire-il-codice-java-dal-terminale/</link>
                <guid isPermaLink="false">64f3313421109103fd7ba95c</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paola Rosati ]]>
                </dc:creator>
                <pubDate>Tue, 12 Sep 2023 09:34:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/09/Run-Java-Using-The-Terminal---freeCodeCamp-Cover-image.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/how-to-execute-and-run-java-code/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Execute and Run Java Code from the Terminal</a>
      </p><p>Se lavori con Java, probabilmente hai usato uno dei più famosi editor di testo come Sublime Text, VS Code, Brackets, Atom, e Notepad++, o anche IDE come Apache NetBeans e IntelliJ IDEA.</p><p>Eseguire il codice nel tuo IDE è immediato, ma spesso non riesci a vedere in che modo viene eseguito il codice (anche se ovviamente puoi controllare il comando nel terminale).</p><p>Tuttavia, è buona prassi sapere come viene eseguito effettivamente il codice e come viene prodotto l'output che ti restituisce.</p><p>Molti di voi potrebbero aver sentito che gli sviluppatori professionisti esperti usano anche il terminale per eseguire i programmi. Questo dà loro una visione più chiara e li aiuta a capire in che modo sta funzionando il codice, dove sta restituendo il valore desiderato, dove potrebbe trovarsi un bug, e così via.</p><p>Qualsiasi sia l'obiettivo, eseguire il codice Java direttamente dal terminale è un lavoro molto semplice.</p><p>In questo articolo ti mostrerò come puoi eseguire il codice Java direttamente dalla tua finestra del terminale preferita. Non temere! La procedura è abbastanza semplice, e dopo aver letto l'intero articolo dovresti essere in grado di eseguire il tuo codice Java dal terminale.</p><h2 id="come-eseguire-il-codice-java-nel-terminale"><strong>Come Eseguire il Codice Java nel Terminale</strong></h2><p>Il processo che sto per mostrarti in questo articolo si applica a qualsiasi sistema operativo, che sia Windows, MacOS o Linux.</p><p>Userò il seguente codice Java nel prossimo passaggio.</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, World!"); 
    }
}</code></pre><h2 id="-step-1-vai-nella-cartella-dove-si-trova-il-codice-sorgente"><strong>📦 Step 1 – Vai nella cartella dove si trova il codice sorgente</strong></h2><p>Se hai già scritto il tuo codice Java in un editor, allora vai semplicemente in quella cartella. Puoi andare direttamente nella cartella usando il gestore dei file se vuoi.</p><h3 id="come-andare-nella-cartella-dove-si-trova-il-codice-sorgente-per-windows-"><strong>Come andare nella cartella dove si trova il codice sorgente: per Windows 🪟</strong></h3><p>Supponiamo di avere il codice sorgente (<code>Main.java</code>) dentro la cartella <code>This PC</code> &gt; <code>Documents</code>. Posso andare lì semplicemente usando Esplora File.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Untitled.png" class="kg-image" alt="Untitled" width="600" height="400" loading="lazy"></figure><p>Oppure, volendo, posso anche andarci usando il mio terminale. Devo usare <code>cd</code> (da "change directory" in inglese) per indicare che voglio <strong>cambiare cartella</strong> .</p><p>In questo caso, posso usare <code>cd "C:\Users\Md. Fahim Bin Amin\Documents"</code>. Poiché il mio nome utente contiene degli spazi, ho usato <code>"</code> <code>"</code> per racchiuderli.</p><p>Poi se controllo tutti i file all'interno di quella cartella, vedrò anche il file <code>Main.java</code>.</p><p>Ho messo il file <code>Main.java</code> nel mio drive <strong><strong>D</strong></strong> questa volta. Quindi sono andato in quella cartella usando il comando <code>cd</code>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-08-022040.png" class="kg-image" alt="Screenshot-2022-03-08-022040" width="600" height="400" loading="lazy"></figure><p>Vedo il mio file Java anche nel terminale.</p><h3 id="come-andare-nella-cartella-dove-si-trova-il-codice-sorgente-per-linux-"><strong>Come andare nella cartella dove si trova il codice sorgente: per Linux 🐧</strong></h3><p>Puoi andare nella cartella dove si trova il tuo codice sorgente sia attraverso la GUI o dal terminale usando il comando <code>cd</code> anche qui.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-10-124200.png" class="kg-image" alt="Screenshot-2022-03-10-124200" width="600" height="400" loading="lazy"><figcaption>Usando la GUI</figcaption></figure><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/italian/news/content/images/2023/09/image.png" class="kg-image" alt="image" srcset="https://www.freecodecamp.org/italian/news/content/images/size/w600/2023/09/image.png 600w, https://www.freecodecamp.org/italian/news/content/images/2023/09/image.png 723w" width="723" height="456" loading="lazy"><figcaption>Usando il comando <code>cd</code></figcaption></figure><h2 id="-come-compilare-il-codice-java"><strong>🧑‍💻Come Compilare il Codice Java</strong></h2><p>Prima di eseguire il nostro codice Java, dobbiamo compilarlo. Per compilare un codice/programma in Java, otteniamo il file class che in seguito dovremo eseguire.</p><h3 id="come-compilare-il-codice-java-usando-il-terminale"><strong>Come compilare il codice Java usando il terminale</strong></h3><p>Dobbiamo usare il comando <code>javac nome_file_con_estensione</code>. Per esempio, dato che voglio compilare il mio <code>Main.java</code>, userò il comando <code>javac Main.java</code>. La <code>c</code> in <code>javac</code> sta per compila.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-10-122312.png" class="kg-image" alt="Screenshot-2022-03-10-122312" width="600" height="400" loading="lazy"></figure><p>Se il processo di compilazione avviene con successo, non otterremo nessun errore.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-10-122345.png" class="kg-image" alt="Screenshot-2022-03-10-122345" width="600" height="400" loading="lazy"></figure><p>Questo creerà il file class di cui abbiamo bisogno nella stessa cartella.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-10-122628.png" class="kg-image" alt="Screenshot-2022-03-10-122628" width="600" height="400" loading="lazy"></figure><p>Tieni a mente che eseguiamo il file <strong>class</strong>, non il file <code>.java</code>.</p><p>Lo stesso processo è applicabile per tutti i sistemi operativi disponibili.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-10-124951.png" class="kg-image" alt="Screenshot-2022-03-10-124951" width="600" height="400" loading="lazy"><figcaption>in Linux OS</figcaption></figure><h2 id="-come-eseguire-il-codice-java"><strong>🖥️ Come Eseguire il Codice Java</strong></h2><p>Eseguiamo il file <code>.class</code> per lanciare i programmi Java. Per questo, usiamo il comando <code>java nome_file_class_senza_estensione</code>. Per esempio, poiché il nostro file <code>.class</code> per questo programma è <code>Main.class</code>, il nostro comando sarà <code>java Main</code>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-10-125223.png" class="kg-image" alt="Screenshot-2022-03-10-125223" width="600" height="400" loading="lazy"></figure><p>Il programma Java è stato eseguito con successo!</p><p>La stessa identica procedura è applicabile anche ad altri sistemi operativi.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-10-125317.png" class="kg-image" alt="Screenshot-2022-03-10-125317" width="600" height="400" loading="lazy"><figcaption>in Linux OS</figcaption></figure><h2 id="-bonus-come-eseguire-un-programma-java-con-i-package"><strong>🏅Bonus: Come Eseguire un Programma Java con i Package</strong></h2><p>Un package sta praticamente ad indicare una cartella. Prima ti ho mostrato come usare un qualsiasi normale codice Java ricorrendo al terminale. Lì non ho usato alcun package all'interno del codice Java.</p><p>Adesso ti mostrerò come puoi eseguire qualsiasi codice Java che ha dei package dichiarati al suo interno. Questa volta, userò il seguente codice Java.</p><pre><code class="language-java">package myJavaProgram.Source;
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, World!"); 
    }
}</code></pre><p>Nella prima riga ho scritto il package come <code>package myJavaProgram.Source</code>. Questo indica che voglio creare una cartella chiamata <code>myJavaProgram</code>. Poi, voglio creare un'altra cartella al suo interno chiamata <code>Source</code>. Infine, voglio creare un file class del mio codice Java all'interno della cartella <code>Source</code>.</p><p>La struttura ad albero delle cartelle sarà la seguente: <strong><strong>myJavaProgram &gt; Source.</strong></strong></p><p>Per compilare questo tipo di codice Java con i package, usiamo il comando <code>javac -d . nome_file_con_estensione</code>.</p><p>Al momento sto usando il file <code>Main.java</code>, quindi userò il comando <code>javac -d . Main.java</code>. Questo creerà una cartella chiamata <strong><strong>myJavaProgram</strong></strong>, poi creerà un'altra cartella chiamata <strong><strong>Source </strong></strong>dentro la cartella <strong><strong>myJavaProgram </strong></strong>dentro la cartella dove si trova il mio file sorgente.</p><ul><li>La_Cartella_Dove_Ho_Il_Mio_Codice_Sorgente</li><li>cartella <code>myJavaProgram</code></li><li>cartella <code>Source</code> </li></ul><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-10-134626.png" class="kg-image" alt="Screenshot-2022-03-10-134626" width="600" height="400" loading="lazy"></figure><p>Crea istantaneamente la cartella <strong><strong>myJavaProgram</strong></strong>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-10-134710.png" class="kg-image" alt="Screenshot-2022-03-10-134710" width="600" height="400" loading="lazy"></figure><p>All'interno della cartella, crea la cartella <strong><strong>Source</strong></strong>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-10-134806.png" class="kg-image" alt="Screenshot-2022-03-10-134806" width="600" height="400" loading="lazy"></figure><p>Dentro la cartella Source, crea il nostro file <code>.class</code>. Abbiamo bisogno di questo file per eseguire il programma Java.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-10-134853.png" class="kg-image" alt="Screenshot-2022-03-10-134853" width="600" height="400" loading="lazy"></figure><p>Adesso, se vogliamo eseguire il file <code>.class</code>, abbiamo bisogno di cambiare un po' il comando, poiché dobbiamo fornire la cartella del file <code>.class</code> nella finestra del terminale.</p><p>Usiamo il comando per eseguire il programma Java con i package, <code>java cartella_del_file_class.il_nome_del_file_class_senza_estensione</code>.</p><p>Poiché sto usando <code>Main.java</code> e ho bisogno di eseguire il file <code>Main.class</code>, il mio comando sarà <code>java myJavaProgram.Source.Main</code>. Eseguirà il codice Java come qui di seguito.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-10-135226.png" class="kg-image" alt="Screenshot-2022-03-10-135226" width="600" height="400" loading="lazy"></figure><p>Se ti stai chiedendo perché stiamo cambiando il comando adesso, è perché prima non abbiamo dichiarato nessun package. Quindi il compilatore Java ha creato il file <code>.class</code> all'interno della cartella dove si trovava il nostro codice sorgente. Quindi, potremmo prendere il file <code>.class</code> direttamente da lì e potremmo anche eseguire il file class.</p><p>Ma se dichiariamo i package all'interno del codice sorgente in questo modo, allora stiamo dicendo al compilatore di creare il file <code>.class</code> in un altro posto (non all'interno della cartella dove si trova il nostro codice sorgente). Ciò significa che non prendiamo il file class direttamente da lì.</p><p>Poiché vogliamo eseguire il file class, abbiamo bisogno di dire al compilatore esplicitamente dove si trova il file class al momento, così che possa prendere il file class ed eseguirlo.</p><p>Se pensi di poter fare confusione durante questo passaggio, allora puoi copiare la cartella direttamente dal tuo codice Java.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-10-135404.png" class="kg-image" alt="Screenshot-2022-03-10-135404" width="600" height="400" loading="lazy"></figure><p>Nella riga 1, abbiamo dichiarato la cartella del package (dove vogliamo che sia generato il file class). Dunque, se copiamo semplicemente la cartella e aggiungiamo il nome del file <code>.class</code> senza l'estensione (<code>.class</code>), preceduto da un punto (<code>.</code>), allora soddisfiamo la condizione per eseguire qualsiasi codice Java che ha dei package dichiarati nel codice sorgente.</p><p>Lo stesso processo è applicabile agli altri sistema operativi. Ecco qui degli screenshot da un sistema Linux:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2022/03/Screenshot-2022-03-10-140017.png" class="kg-image" alt="Screenshot-2022-03-10-140017" width="600" height="400" loading="lazy"><figcaption>Eseguire codici Java con dei package all'interno su Linux</figcaption></figure><p>Ottimo lavoro! 👏 Adesso puoi eseguire qualsiasi codice/programma Java direttamente usando un terminale. 🥳</p><p>Ho creato anche un video dove ho mostrato tutti i procedimenti menzionati in alto. Puoi darci un'occhiata <a href="https://www.youtube.com/watch?v=e_lmKSCH9YE">qui</a>. 😁</p><h2 id="-conclusione"><strong>💁‍♂️ Conclusione</strong></h2><p>Spero che questo articolo ti aiuti ad eseguire i tuoi programmi Java usando solo il terminale.</p><p>➡️ Se vuoi sapere come installare un compilatore Java per il tuo sistema operativo Windows, <a href="https://www.freecodecamp.org/news/how-to-install-java-on-windows/">allora puoi dare un'occhiata a questo articolo</a>.</p><p>➡️ Se vuoi sapere come installare dei compilatori per C e C++ sul tuo sistema operativo Windows, <a href="https://www.freecodecamp.org/news/how-to-install-c-and-cpp-compiler-on-windows/">allora puoi dare un'occhiata a questo articolo</a>.</p><p>➡️ Se vuoi sapere come installare Python sul tuo sistema operativo Windows, <a href="https://www.freecodecamp.org/news/how-to-install-python-in-windows-operating-system/">allora puoi dare un'occhiata a questo articolo</a>.</p><p>Grazie per aver letto l'intero articolo. Se ti può essere di aiuto puoi anche dare un'occhiata ai miei altri articoli su <a href="https://www.freecodecamp.org/news/author/fahimbinamin/">freeCodeCamp</a>.</p><p>Se vuoi metterti in contatto con me, puoi farlo usando <a href="https://twitter.com/Fahim_FBA">Twitter</a>, <a href="https://www.linkedin.com/in/fahimfba/">LinkedIn</a>, e <a href="https://github.com/FahimFBA">GitHub</a>.</p><p>Puoi anche <a href="https://www.youtube.com/@FahimAmin?sub_confirmation=1">ISCRIVERTI al mio canale di YouTube</a> (Code With FahimFBA) se vuoi imparare diversi tipi di linguaggi di programmazione con molti esempi pratici pubblicati regolarmente.</p><p>Se vuoi dare un'occhiata ai miei highlights, puoi farlo sulla mia <a href="https://www.polywork.com/fahimbinamin">timeline Polywork</a>.</p><p>Puoi anche <a href="https://fahimbinamin.com/">visitare il mio sito</a> per saperne di più di me e delle cose su cui sto lavorando.</p><p>Grazie mille!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Garbage Collection in Java: Che Cos'è e Come Funziona la GC nella JVM ]]>
                </title>
                <description>
                    <![CDATA[ Nel mio precedente articolo [/italian/news/tutorial-jvm-larchitettura-della-java-virtual-machine-spiegata-per-principianti/] , ho trattato la Java Virtual Machine (JVM) e ne ho descritto l'architettura. Inoltre, ho introdotto brevemente il Java Garbage Collector (GC, letteralmente "raccoglitore della spazzatura", netturbino) come parte del componente del motore di esecuzione. In questo articolo, approfondiremo l'argomento del Garbage Collector, il suo ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/garbage-collection-in-java/</link>
                <guid isPermaLink="false">63ea9d1d87f2e0059ba2cc78</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Marcello Tora ]]>
                </dc:creator>
                <pubDate>Mon, 20 Feb 2023 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/02/GC.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/garbage-collection-in-java-what-is-gc-and-how-it-works-in-the-jvm/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Garbage Collection in Java – What is GC and How it Works in the JVM</a>
      </p><p>Nel mio <a href="https://www.freecodecamp.org/italian/news/tutorial-jvm-larchitettura-della-java-virtual-machine-spiegata-per-principianti/">precedente articolo</a>, ho trattato la Java Virtual Machine (JVM) e ne ho descritto l'architettura. Inoltre, ho introdotto brevemente il Java Garbage Collector (GC, letteralmente "raccoglitore della spazzatura", netturbino) come parte del componente del motore di esecuzione.</p><p>In questo articolo, approfondiremo l'argomento del Garbage Collector, il suo funzionamento e i diversi tipi di GC disponibili nell'ambiente Java, assieme ai loro vantaggi. Saranno inoltre inclusi nella spiegazione anche alcuni dei nuovi Garbage Collector sperimentali e disponibili solamente nelle più recenti release Java.</p><h2 id="che-cos-la-garbage-collection-in-java"><strong>Che cos'è la Garbage Collection in Java?</strong></h2><p>La Garbage Collection (la raccolta della spazzatura) è il processo di recupero della memoria di runtime allocata ma inutilizzata che viene attuato mediante la distruzione degli oggetti inutilizzati.</p><p>In linguaggi come C e C++, è il programmatore a essere responsabile sia per la creazione che la distruzione degli oggetti. Talvolta, il programmatore può dimenticare di eliminare oggetti obsoleti e in questo modo la memoria allocata per accoglierli non viene liberata. La memoria utilizzata continua a crescere fino a quando non rimane più memoria da allocare. Applicazioni con questo comportamento soffrono di "<em>memory leak</em>" (falle, perdite di memoria).</p><p>Superata una certa soglia, non rimane più memoria libera in quantità sufficiente per la creazione di nuovi oggetti e l'intero programma termina in modo anomalo a causa di eccezioni di tipo OutOfMemoryError.</p><p>Si possono utilizzare metodi come <code>free()</code> in C e <code>delete()</code> in C++ per eseguire esplicitamente la Garbage Collection. In Java, la garbage collection avviene in modo automatico durante il ciclo di vita di un programma. Questa caratteristica elimina la necessità di de-allocare memoria e di conseguenza protegge dalle memory leak.</p><p>La Java Garbage Collection è il processo attraverso il quale Java esegue la gestione automatica della memoria. I programmi Java si compilano in bytecode che può essere eseguito su una Java Virtual Machine (JVM).</p><p>Quando i programmi Java sono eseguiti sulla JVM, gli oggetti sono creati sull'heap, che è un'area della memoria dedicata al programma.</p><p>Durante il ciclo di vita di un'applicazione Java, nuovi oggetti sono creati e rilasciati. Alla fine, alcuni oggetti diventeranno obsoleti. In particolare, possiamo dire che in un qualsiasi momento nel tempo, la memoria contenuta nell'heap è occupata da due tipi di oggetti:</p><ul><li><em>Vivi </em>- questi oggetti sono utilizzati e referenziati in altre parti del programma</li><li><em>Morti</em> - questi oggetti non sono più utilizzati né referenziati in una qualunque parte del programma</li></ul><p>Il garbage collector individua gli oggetti obsoleti non più utilizzati per poi eliminarli liberando memoria. </p><h2 id="come-de-referenziare-un-oggetto-in-java"><strong>Come de-referenziare un oggetto in Java</strong></h2><p>L'obiettivo principale della Garbage Collection è liberare memoria dall'heap distruggendo tutti quegli oggetti che non contengono un riferimento. Quando non vi sono riferimenti a un oggetto, si assume che sia obsoleto e non più necessario. In questo modo la memoria occupata dall'oggetto può essere reclamata.</p><p>Vi sono vari modi attraverso i quali le referenze verso un oggetto possono essere rilasciate per renderlo un potenziale candidato scelto dalla Garbage Collection. Alcuni di questi sono i seguenti:</p><h3 id="assegnare-null-ad-un-riferimento">Assegnare null ad un riferimento</h3><pre><code class="language-java">Student student = new Student();
student = null;</code></pre><h3 id="assegnare-un-riferimento-a-un-altro"><strong>Assegnare un riferimento a un altro</strong></h3><pre><code class="language-java">Student studentOne = new Student();
Student studentTwo = new Student();
studentOne = studentTwo; // ora il primo oggetto referenziato da studentOne è disponibile per il passaggio del Garbage Collector</code></pre><h3 id="utilizzare-un-oggetto-anonimo"><strong>Utilizzare un oggetto anonimo</strong></h3><pre><code class="language-java">register(new Student());</code></pre><h2 id="come-funziona-la-garbage-collection-in-java"><strong>Come funziona la Garbage Collection in Java?</strong></h2><p>La Garbage Collection in ambiente Java è un processo automatico. Il programmatore non ha l'onere di indicare esplicitamente quali oggetti destinare alla cancellazione.</p><p>L'implementazione delle garbage collection vive all'interno della JVM. Ciascuna JVM può implementare la propria versione di garbage collection. Tuttavia, deve sempre rispettare la specifica standard della JVM che richiede di lavorare con gli oggetti presenti nella porzione heap della memoria, segnalando o identificando gli oggetti divenuti irraggiungibili e distruggendoli con la compattazione.</p><h2 id="cosa-sono-le-radici-della-garbage-collection-in-java"><strong>Cosa sono le radici della Garbage Collection in Java?</strong></h2><p>I garbage collector funzionano basandosi sul concetto di radici della Garbage Collection (GC Roots) per distinguere gli oggetti vivi da quelli morti.</p><p>Esempi di tali radici son i seguenti:</p><ul><li>Classi caricate dal class loader di sistema (non da class loader custom)</li><li>Thread attivi</li><li>Variabili locali e parametri dei metodi attualmente in esecuzione</li><li>Variabili locali e parametri dei metodi dei metodi JNI</li><li>Riferimenti JNI globali</li><li>Oggetti utilizzati come monitor per la sincronizzazione</li><li>Oggetti utilizzati dalla JVM la quale li trattiene impedendo che finiscano distrutti dalla garbage collection</li></ul><p>Il garbage collector attraversa l'intero grafo nella memoria, iniziando dalle radici e seguendo i riferimenti da queste verso gli altri oggetti.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-76.png" class="kg-image" alt="image-76" width="600" height="400" loading="lazy"></figure><h2 id="le-fasi-della-garbage-collection-in-java">Le fasi della Garbage Collection in Java</h2><p>Un'implementazione standard di Garbage Collection comprende tre fasi:</p><h3 id="marcatura-degli-oggetti-vivi"><strong>Marcatura degli oggetti vivi</strong></h3><p>In questo step, il GC individua tutti gli oggetti vivi in memoria attraversando il grafo degli oggetti.</p><p>Quando il GC visita un oggetto, lo marca come accessibile e quindi lo classifica come vivo. Ciascun oggetto visitato dal garbage collector è considerato vivo. Analogamente, tutti gli oggetti che non sono raggiungibili a partire dalle radici sono considerati oggetti morti e potenziali candidati per la garbage collection. </p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-82.png" class="kg-image" alt="image-82" width="600" height="400" loading="lazy"></figure><h3 id="pulizia-degli-oggetti-obsoleti"><strong>Pulizia degli oggetti obsoleti</strong></h3><p>Dopo la fase di marcatura, siamo nella condizione in cui lo spazio di memoria è occupato dagli oggetti vivi (visitati) e dagli oggetti morti (non raggiungibili, non visitati). La fase di pulizia della memoria ha l'effetto di svuotare tutti i frammenti di memoria che prima erano occupati dagli oggetti morti.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-83.png" class="kg-image" alt="image-83" width="600" height="400" loading="lazy"></figure><h3 id="compattazione-degli-oggetti-rimanenti-in-memoria"><strong>Compattazione degli oggetti rimanenti in memoria</strong></h3><p>Gli oggetti morti rimossi durante la fase di pulizia potrebbero non aver occupato segmenti di memoria adiacenti. Pertanto, è probabile che si finisca per ottenere uno spazio di memoria frammentato.</p><p>La memoria può essere compattata dopo la cancellazione degli oggetti morti, in modo che gli oggetti rimanenti occupino un blocco contiguo di memoria che comincia all'inizio dell'area di heap.</p><p>Il processo di compattazione rende più facile allocare la memoria per i nuovi oggetti in modo sequenziale, assegnando indirizzi via via crescenti.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-85.png" class="kg-image" alt="image-85" width="600" height="400" loading="lazy"></figure><h2 id="che-cosa-si-intende-per-garbage-collection-generazionale-in-java"><strong>Che cosa si intende per Garbage Collection generazionale in Java?</strong></h2><p>I Java Garbage Collector implementano una strategia di <em>garbage collection</em> <em>generazionale </em>che classifica gli oggetti distinguendoli in classi di età.</p><p>Il compito di marcare e compattare tutti gli oggetti presenti in una JVM è un processo inefficiente. Con l'aumentare degli oggetti allocati, la lista degli oggetti cresce, e si allungano i tempi richiesti dalla garbage collection. L'analisi empirica delle applicazioni ha dimostrato che la maggior parte degli oggetti in Java ha vita breve.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/01/ObjectLifetime.gif" class="kg-image" alt="ObjectLifetime" width="600" height="400" loading="lazy"><figcaption>Source: oracle.com</figcaption></figure><p>Nell'esempio qui sopra, l'asse Y indica il numero di byte sopravvissuti o mantenuti, mentre l'asse X rappresenta il numero di byte allocati al passare del tempo. Come si può notare, in un intervallo di tempo abbastanza lungo, rimangono sempre meno oggetti allocati.</p><p>Infatti, la gran parte degli oggetti ha una vita molto breve, come dimostrato dai valori più alti vicino all'asse Y del grafico. Questo avviene perché Java classifica gli oggetti in generazioni e applica i cicli di garbage collection coerentemente con tale classificazione.</p><p>L'area di memoria riservata all'heap nella JVM è suddivisa in tre sezioni:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-70.png" class="kg-image" alt="image-70" width="600" height="400" loading="lazy"></figure><h2 id="generazione-giovane"><strong>Generazione Giovane</strong></h2><p>I nuovi oggetti iniziano il loro ciclo di vita nella Generazione Giovane (Young Generation). A sua volta, la generazione giovane viene suddivisa in:</p><ul><li><strong>Spazio Eden</strong> - tutti i nuovi oggetti partono in questo spazio quando ricevono l'allocazione di memoria iniziale</li><li><strong>Spazi destinati ai sopravvissuti<strong> (FromSpace</strong> e<strong> ToSpace)</strong></strong> - gli oggetti vengono trasferiti qui dallo spazio Eden dopo essere sopravvissuti al primo ciclo di garbage collection.</li></ul><p>Il momento in cui il garbage collector rimuove gli oggetti dall'area di Generazione Giovane, è indicato come <em>evento di garbage collection minore</em>. </p><p>Quando lo spazio Eden è stato popolato con gli oggetti, viene eseguito un ciclo di GC minore. &nbsp;Tutti gli oggetti marcati come morti sono rimossi, mentre tutti gli oggetti marcati come vivi sono trasferiti ad uno degli spazi destinati ai sopravvissuti. L'evento di GC minore verifica anche gli oggetti presenti negli spazi dei sopravvissuti e li trasferisce da uno spazio all'altro.</p><p>Esaminiamo la seguente sequenza di esempio:</p><ol><li>Tutti gli oggetti sono inseriti nello spazio Eden (sia vivi che morti)</li><li>Viene eseguito il ciclo di GC minore - tutti gli oggetti morti vengono estratti dallo spazio Eden. Tutti gli oggetti vivi sono trasferiti allo spazio dei sopravvissuti S1 (FromSpace). A questo punto lo spazio Eden è stato svuotato e lo spazio dei sopravvissuti S2 è vuoto.</li><li>I nuovi oggetti sono creati e aggiunti allo spazio Eden. Alcuni oggetti in S1 e nello spazio Eden vengono classificati come morti.</li><li>Viene eseguito un ciclo di GC minore - tutti gli oggetti morti sono rimossi da Eden ed S1. Tutti gli oggetti vivi sono trasferiti a S2 (ToSpace). Lo spazio Eden e lo spazio S1 adesso sono stati svuotati.</li></ol><p>Pertanto, in qualsiasi momento, uno dei due spazi destinati agli oggetti sopravvissuti è sempre vuoto. Quando gli oggetti sopravvissuti raggiungono una certa soglia di trasferimenti da uno spazio dei sopravvissuti all'altro, vengono inviati alla Generazione Vecchia (Old Generation).</p><p>Per impostare la dimensione della Generazione Giovane è possibile usare l'apposito flag <code>-Xmn</code> .</p><h2 id="generazione-vecchia"><strong>Generazione Vecchia</strong></h2><p>Gli oggetti che sopravvivono più a lungo vengono ad un certo punto spostati dalla Generazione Giovane alla Generazione Vecchia. Quest'ultima è anche conosciuta come la Generazione "di ruolo" e contiene gli oggetti che sono stati mantenuti negli spazi dei sopravvissuti per un tempo relativamente lungo.</p><p>È definito un preciso valore di soglia per il mandato di ciascun oggetto che determina il numero dei cicli di garbage collection a cui l'oggetto deve sopravvivere prima che venga trasferito allo spazio della Generazione Vecchia.</p><p>Quando gli oggetti presenti nella Generazione Vecchia vengono raccolti dal garbage collector, è indicato come <em>evento di garbage collection maggiore</em>.</p><p>Per impostare la dimensione iniziale e quella massima raggiungibile dall'area Heap della memoria è possibile agire, rispettivamente, sugli appositi flag <code>-Xms</code> e <code>-Xmx</code>.</p><p>Dato il funzionamento della garbage collection generazionale utilizzata in Java, più è alto il numero di cicli di garbage collection a cui un evento sopravvive, più avanti in termini di indirizzo verrà spostato all'interno dell'heap. Inizia la sua vita nella Generazione Giovane e, alla fine, potrà giungere alla Generazione "di ruolo", se sopravvivrà ad un numero di cicli sufficiente.</p><p>Consideriamo l'esempio seguente per comprendere la promozione degli oggetti attraverso gli spazi e le generazioni:</p><p>Quando un oggetto viene creato, è inserito inizialmente nello <strong>Spazio Eden</strong> all'interno della <strong>Generazione Giovane</strong>. Dopo l'intervento di un ciclo di garbage collection minore, gli oggetti vivi presenti nello <strong>spazio Eden</strong> sono promossi nello spazio dei sopravvissuti <strong>FromSpace</strong>. Quando si verifica il successivo ciclo di garbage collection minore, gli oggetti vivi presenti sia nello <strong>spazio Eden</strong> che nel <strong>FromSpace</strong> sono trasferiti al <strong>ToSpace</strong>.</p><p>Questa successione di eventi è ripetuta per un numero predefinito di iterazioni, raggiunto il quale, qualora l'oggetto risultasse ancora utilizzato, viene destinato alla <strong>Generazione Vecchia</strong> a partire dal ciclo di garbage collection successivo.</p><h2 id="generazione-permanente"><strong>Generazione Permanente</strong></h2><p>I metadati come classi e metodi sono memorizzati nella Generazione Permanente. Viene popolata dalla JVM al runtime sulla base delle classi in uso dall'applicazione. Le classi presenti nella Generazione Permanente che non risultano più in uso potrebbero essere raccolte dal garbage collector.</p><p>Per impostare le dimensioni iniziale e massima della Generazione Permanente sono previsti rispettivamente i flag &nbsp;<code>-XX:PermGen</code> e <code>-XX:MaxPermGen</code>.</p><h2 id="metaspace"><strong>MetaSpace</strong></h2><p>A partire dalla versione 8 di Java, lo spazio di memoria <strong>MetaSpace </strong>sostituisce lo spazio <strong>PermGen</strong>. La nuova implementazione differisce dal PermGen e adesso questa porzione di heap viene ridimensionata in modo automatico.</p><p>Questo evita il problema dell'esaurimento di memoria da parte delle applicazioni a causa della dimensione limitata dello spazio PermGen nell'heap. La memoria MetaSpace può essere pulita tramite la garbage collection e le classi che non vengono più utilizzate possono essere rimosse automaticamente quando il MetaSpace raggiunge la dimensione massima.</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.178026315789474%;" class="fluid-width-video-wrapper">
            <iframe src="https://www.youtube.com/embed/X1DkoRGVRp4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" title="Embedded content" loading="lazy" name="fitvid0" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 22px; vertical-align: middle; position: absolute; top: 0px; left: 0px; width: 760px; height: 426.953px;"></iframe>
          </div>
        </div>
      </figure><h2 id="tipi-di-garbage-collector-nella-java-virtual-machine"><strong>Tipi di Garbage Collector nella Java Virtual Machine</strong></h2><p>La garbage collection rende la memoria Java efficiente perché rimuove gli oggetti non più referenziati dall'heap liberando spazio che diventa disponibile per l'allocazione dei nuovi oggetti.</p><p>La Java Virtual Machine dispone di otto tipi diversi di garbage collector. Vediamo di seguito i dettagli per ciascuna tipologia.</p><h2 id="seriale">Seriale</h2><p>Si tratta della più semplice implementazione di GC che è stata progettata per piccole applicazioni eseguite su ambienti in modalità mono-thread. Tutti gli eventi di garbage collection sono eseguiti sequenzialmente in un unico thread. La compattazione è eseguita dopo ciascun ciclo di collection.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-68.png" class="kg-image" alt="image-68" width="600" height="400" loading="lazy"></figure><p>Quando viene eseguito, determina un evento "stop the world" (letteralmente "arresta, interrompi il mondo") in corrispondenza del quale l'intera applicazione è posta in pausa. Dato che l'intera applicazione è congelata per la durata della garbage collection, non è consigliato per scenari del mondo reale nel quale sono generalmente richieste latenze ridotte.</p><p>L'argomento della JVM utilizzato per impostare il GC Seriale è <code>-XX:+UseSerialGC</code>.</p><h2 id="parallelo"><strong>Parallelo</strong></h2><p>Il collector parallelo è adatto ad applicazioni con data set di dimensioni comprese tra medie e grandi che siano eseguite su di un hardware multiprocessore in modalità multi-thread. Questa è l'implementazione di default per il GC nella JVM ed è anche conosciuto come Throughput Collector.</p><p>Sono utilizzati thread multipli per gli eventi minori di garbage collection verso la Generazione Giovane. Un singolo thread gestisce invece gli eventi maggiori di collection sulla Generazione Vecchia.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-66.png" class="kg-image" alt="image-66" width="600" height="400" loading="lazy"></figure><p>Eseguire il GC Parallelo determina comunque un evento "stop the world" e il congelamento dell'applicazione. Dato che è più adatto ad un ambiente multi-thread, può essere utilizzato quando una gran quantità di lavoro deve essere completata e pause lunghe sono ritenute accettabili, ad esempio eseguendo un job batch.</p><p>L'argomento della JVM da impostare per l'utilizzo del Garbage Collector Parallelo è &nbsp;<code>-XX:+UseParallelGC</code>.</p><h2 id="vecchio-gc-parallelo"><strong>Vecchio GC Parallelo</strong></h2><p>Questa è la versione di default del GC Parallelo a partire dalla versione Java 7u4. Ha le medesime caratteristiche del GC Parallelo tranne per il fatto che sfrutta thread multipli sia per eseguire collection sulla Generazione Giovane che sulla Generazione Vecchia.</p><p>L'argomento da passare alla JVM per utilizzare il Garbage Collector Parallelo Vecchio è invece <code>-XX:+UseParallelOldGC</code>.</p><h2 id="cms-concurrent-mark-sweep-pulizia-e-marcatura-concorrenti-"><strong>CMS - Concurrent Mark Sweep (Pulizia e Marcatura Concorrenti)</strong></h2><p>Anche conosciuto come il collector concorrente con pausa ridotta. Utilizza thread multipli per eventi di garbage collection minore implementando lo stesso algoritmo del Parallelo. La garbage collection maggiore è implementata in multi-thread, analogamente a quanto avveniva con il Vecchio GC Parallelo, ma nel caso del CMS, è eseguita in concorrenza con i processi dell'applicazione in modo da minimizzare le occorrenze di eventi "stop the world".</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-67.png" class="kg-image" alt="image-67" width="600" height="400" loading="lazy"></figure><p>A causa di ciò, il collector CMS necessita di maggiori risorse di CPU rispetto agli altri GC. Se nel sistema vi è disponibilità per allocare una quantità maggiore di risorse CPU per ottenere performance migliori, allora il collector CMS sarà una scelta migliore rispetto al collector Parallelo. La compattazione non è invece eseguita dal collector CMS.</p><p>L'argomento per la JVM da utilizzare per impostare il GC Concurrent Mark Sweep è invece &nbsp;<code>-XX:+UseConcMarkSweepGC</code>.</p><h2 id="g1-garbage-first-prima-la-spazzatura-"><strong>G1 - Garbage First (Prima la spazzatura) </strong></h2><p>Il G1 era stato pensato per sostituire CMS ed era progettato per applicazioni multi-thread con un ampio spazio di memoria heap (superiore a 4GB) a disposizione. Si tratta di un'implementazione parallela e concorrente come il CMS, ma che funziona diversamente se paragonata ai garbage collector più vecchi.</p><p>Nonostante anche G1 condivida l'approccio generazionale, non utilizza regioni separate per le generazioni giovane e vecchia. Invece, ciascuna generazione costituisce un insieme di regioni, le quali consentono il ridimensionamento della generazione giovane in modo flessibile.</p><p>L'heap viene partizionato in un insieme di regioni di egual dimensione (da 1MB a 32MB - a seconda della dimensione dell'heap) e utilizza thread multipli per la scansione delle stesse. Una regione potrebbe essere classificata sia come vecchia che come nuova in un momento qualsiasi durante l'esecuzione del programma.</p><p>Dopo il completamento della fase di marcatura, G1 è in grado di individuare quali regioni contengano la gran parte degli oggetti da pulire. Se l'utente è interessato a ridurre al minimo i tempi di pausa, G1 può scegliere di rimuovere solo poche regioni. Se, al contrario, l'user non ha criticità legate ai tempi di pausa oppure ha dichiarato un limite di tempo di pausa sufficientemente elevato, G1 potrebbe scegliere di includere un maggior numero di regioni.</p><p>Dato che G1 identifica la regione con il maggior numero di oggetti da rimuovere ed esegue la garbage collection proprio a partire da quella regione, viene anche detto Garbage First.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-88.png" class="kg-image" alt="image-88" width="600" height="400" loading="lazy"></figure><p>In aggiunta agli spazi Eden, Sopravvissuti e Old, in G1GC sono previsti altri due tipi di regioni:</p><ul><li><em>Enorme (<em>Humongous</em>)</em> - destinato agli oggetti di grandi dimensioni (che richiedono uno spazio superiore al 50% della dimensione dell'heap)</li><li><em>Disponibile (<em>Available</em>)</em> - lo spazio inutilizzato o non allocato</li></ul><p>Per impostare il garbage collector G1 il flag da passare alla JVM è &nbsp;<code>-XX:+UseG1GC</code>.</p><h2 id="epsillon"><strong>Epsillon</strong></h2><p>Epsilon è un collector di tipo "do-nothing" (letteralmente "non fare niente") che è stato rilasciato con la JDK 11. Gestisce l'allocazione della memoria ma senza implementare alcun meccanismo di recupero dello spazio. Una volta che lo spazio disponibile per l'heap viene esaurito, la JVM si arresta.</p><p>Può essere usato per applicazioni ultrasensibili ai vincoli di latenza, nelle quali gli sviluppatori sono in grado di stabilire esattamente l'impronta di occupazione della memoria (footprint), oppure lavorano ad applicazioni ottimizzate a tal punto da essere quasi prive di oggetti obsoleti (garbage-free). L'utilizzo del GC Epsilon al di fuori di questi scenari è in genere sconsigliato.</p><p>Il flag da passare alla JVM per utilizzare il Garbage Collector Epsilon è il seguente <code>-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC</code>.</p><h2 id="shenandoah"><strong>Shenandoah</strong></h2><p>Shenandoah è un nuovo GC rilasciato con la JDK 12. Il principale vantaggio di Shenandoah rispetto a G1 è che svolge una parte maggiore del ciclo della sua garbage collection in modo concorrente con i thread dell'applicazione. G1 può liberare le regioni nell'heap solamente quando l'applicazione è posta in pausa, mentre Shenandoah può trasferire gli oggetti in modo concorrente con l'applicazione.</p><p>Shenandoah può compattare oggetti vivi, rimuovere gli oggetti obsoleti e restituire RAM al Sistema Operativo quasi immediatamente dopo aver rilevato memoria libera. Come conseguenza al fatto che tutte queste attività sono condotte in concorrenza con l'applicazione, Shenandoah necessita di maggiori risorse CPU.</p><p>L'argomento da passare alla JVM per utilizzare il GC Shenandoah è infine il seguente <code>-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC</code>.</p><h2 id="zgc"><strong>ZGC</strong></h2><p>ZGC è un altro GC che è stato inserito nella JDK 11 ed è stato poi migliorato nella JDK 12. È stato pensato per applicazioni che richiedano bassa latenza (con pause inferiori ai 10 ms) e/o che usino un heap molto esteso (dell'ordine dei Terabyte).</p><p>Gli obiettivi primari del ZGC sono latenza contenuta, scalabilità, facilità d'uso. Per raggiungere queste performance, ZGC permette a un'applicazione Java di continuare l'esecuzione mentre vengono eseguite tutte le operazioni di garbage collection. Inoltre, come comportamento di default, ZGC revoca la memoria inutilizzata e la restituisce al sistema operativo.</p><p>In questo modo, ZGC introduce un netto miglioramento rispetto ai GC tradizionali e riuscendo a offrire tempi di pausa estremamente ridotti (tipicamente inferiori ai 2 ms).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2021/01/figure2_600w.jpg" class="kg-image" alt="figure2_600w" width="600" height="400" loading="lazy"><figcaption>Source: oracle.com</figcaption></figure><p>Il flag da impostare sulla JVM per attivare ZGC è invece <code>-XX:+UnlockExperimentalVMOptions -XX:+UseZGC</code>.</p><p><strong>Nota</strong>: con l'introduzione della JDK 15, sia Shenandoah che ZGC sono diventati feature di produzione della JDK dopo essere stati promossi dallo stage sperimentale.</p><h2 id="come-scegliere-il-garbage-collector-pi-adatto"><strong>Come scegliere il Garbage Collector più adatto</strong></h2><p>Quando la tua applicazione non ha stretti vincoli sui tempi di pausa, puoi eseguire l'applicazione lasciando alla JVM la selezione del giusto collector.</p><p>Nella maggior parte degli scenari, le impostazioni di base hanno una buona resa. Se necessario, puoi regolare la dimensione dell'heap per migliorare le performance. Se le performance non sono ancora adeguate, puoi impostare il collector secondo i requisiti dell'applicazione:</p><ul><li><strong><strong>Serial</strong>e</strong> - Se l'applicazione lavora su dati di dimensione contenuta (approssimativamente fino a 100 MB) e/o sarà eseguita su di un singolo processore senza vincoli sui tempi di pausa</li><li><strong><strong>Parallel</strong>o</strong> - Se il picco di performance è la priorità e non ci sono particolari vincoli per quanto riguarda i tempi di pausa e interruzioni di un secondo o maggiori sono ritenute accettabili</li><li><strong><strong>CMS/G1</strong></strong> - Se il tempo di risposta è più importante del rendimento complessivo e le pause dovute all'intervento del garbage collection devono essere limitate approssimativamente a un secondo</li><li><strong><strong>ZGC</strong></strong> - Se il tempo di risposta è critico, e/o si sta lavorando con un heap molto esteso</li></ul><h2 id="vantaggi-della-garbage-collection"><strong>Vantaggi della Garbage Collection</strong></h2><p>I vantaggi dell'azione della garbage collection in Java sono molteplici.</p><p>Prima di tutto, rende il codice più semplice. Non ci si deve preoccupare di gestire cicli di assegnamento e revoca della memoria. È sufficiente smettere di referenziare un oggetto nel codice e, a un certo punto, la memoria occupata dallo stesso oggetto verrà recuperata automaticamente.</p><p>I programmatori che lavorano con linguaggi privi di garbage collection (quali C e C++), devono implementare esplicitamente la gestione della memoria nel proprio codice.</p><p>Rende inoltre Java efficiente in termini di risorse di memoria, in quanto, il garbage collector rimuove gli oggetti non più referenziati dalla regione dell'heap. Ciò determina la creazione di spazio libero di memoria heap per accogliere i nuovi oggetti istanziati dal programma.</p><p>Mentre alcuni programmatori criticano la garbage collection in favore di una gestione più manuale della memoria, la garbage collection è diventata un componente standard per molti altri popolari linguaggi di programmazione.</p><p>Per scenari in cui la garbage collection introduce ricadute negative sulle performance, Java consente molte opzioni per impostare il garbage collector più accuratamente e in modo da migliorare la sua efficienza.</p><h2 id="buone-pratiche"><strong>Buone Pratiche</strong></h2><h3 id="evitare-chiamate-manuali"><strong>Evitare Chiamate Manuali</strong></h3><p>Oltre al funzionamento di base della garbage collection, uno dei punti fondamentali da capire sulla garbage collection in ambiente Java riguarda il fatto che essa segue un comportamento non-deterministico. Questo si traduce nell'impossibilità di predire quando la garbage collection si verificherà durante l'esecuzione.</p><p>È possibile includere un suggerimento nel codice per eseguire il garbage collector, attraverso istruzioni quali chiamate ai metodi <code>System.gc()</code> o <code>Runtime.gc()</code>, ma è importante ricordare che questi non offrono alcuna garanzia che il GC verrà effettivamente richiamato in quel punto del programma.</p><h3 id="utilizzare-strumenti-per-l-analisi"><strong>Utilizzare strumenti per l'analisi</strong></h3><p>Se non si dispone di sufficiente memoria per eseguire l'applicazione, si sperimentano rallentamenti, lunghi tempi di pausa per garbage collection, frequenti eventi di "stop the world" e infine anche errori di "out of memory" (imprevisto esaurimento della memoria). Questo può indicare uno spazio di heap troppo ridotto, ma può anche significare la presenza di memory leak nell'applicazione.</p><p>Si può ottenere aiuto da un tool di monitoraggio come <code>jstat</code> oppure <em><em>Java Flight Recorder</em></em> per comprendere se l'occupazione dell'heap cresca indefinitamente, comportamento che è tipicamente un sintomo di un bug nel codice.</p><h3 id="le-impostazioni-di-default-sono-valide"><strong>Le impostazioni di default sono valide</strong></h3><p>Quando si sta eseguendo una piccola applicazione Java in configurazione standalone, molto probabilmente non si avvertirà la necessità di alcuna impostazione personalizzata della garbage collection. Le impostazioni di default dovrebbero infatti funzionare correttamente nella maggior parte dei casi.</p><h3 id="flag-jvm-per-cambiare-le-impostazioni"><strong>Flag JVM per cambiare le impostazioni</strong></h3><p>L'approccio più corretto per impostare la garbage collection in Java è quello di inserire i flag nella riga di comando della JVM. I Flag possono essere utilizzati per scegliere quale garbage collector applicare (Seriale, G1 e così via), la dimensione iniziale e quella massima dell'heap, la dimensione delle sezioni dell'heap (ad esempio per gli spazi della Generazione Giovane e della Generazione Vecchia) e anche altri parametri.</p><h3 id="scegliere-il-giusto-collector"><strong>Scegliere il giusto collector</strong></h3><p>La natura dell'applicazione da ottimizzare è una buona guida iniziale per effettuare le impostazioni corrette. Ad esempio, il garbage collector parallelo è efficiente ma causa frequenti eventi "stop the world", rendendolo più adatto a processi backend nei quali, pause più lunghe per la garbage collection sono accettabili.</p><p>D'altro canto, il garbage collector CMS è progettato per minimizzare le pause, rendendolo ideale per applicazioni web nelle quali i tempi di risposta sono un fattore critico.</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.178026315789474%;" class="fluid-width-video-wrapper">
            <iframe src="https://www.youtube.com/embed/4sBhc-pSILs?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" title="Embedded content" loading="lazy" name="fitvid1" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 22px; vertical-align: middle; position: absolute; top: 0px; left: 0px; width: 760px; height: 426.953px;"></iframe>
          </div>
        </div>
      </figure><h2 id="conclusione"><strong>Conclusione</strong></h2><p>In questo articolo, abbiamo discusso la Garbage Collection in Java, il suo funzionamento e i diversi tipi di Garbage Collector.</p><p>Per quanto riguarda le applicazioni più semplici, la garbage collection non rientra tra i fattori principali che un programmatore deve considerare durante lo sviluppo. Tuttavia, per i programmatori che vogliono accrescere le proprie abilità in Java, è importante comprendere il funzionamento della garbage collection.</p><p>Si tratta inoltre di un argomento popolare nei colloqui tecnici, sia a livelli junior che senior, per ruoli backend.</p><p>Grazie per essere rimasto con me così a lungo. Spero ti sia piaciuto l'articolo. Puoi connetterti con me su <a href="https://www.linkedin.com/in/theawesomenayak/">LinkedIn</a> dove scrivo post sulla tecnologia e sulla vita. Dai anche un'occhiata <a href="https://www.freecodecamp.org/news/author/theawesomenayak/">a qualche altro mio articolo</a> e al mio canale <a href="https://www.youtube.com/channel/UCmWAaPgfWAkl-Jep5mY-NNg?sub_confirmation=1">YouTube</a>. Buona lettura. 🙂</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Chiamata Saltata del Metodo scanner.nextLine() in Java – Errore Risolto ]]>
                </title>
                <description>
                    <![CDATA[ C'è un errore che spesso disorienta i nuovi programmatori Java. Si verifica quando una serie di prompt di input vengono raggruppati insieme e una delle chiamate del metodo scanner.nextLine() viene saltata – senza alcuna traccia di errore. Dai un'occhiata al seguente snippet, ad esempio: import java.util.Scanner; public class Main { ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/chiamata-saltata-del-metodo-scanner-nextline-in-java-errore-risolto/</link>
                <guid isPermaLink="false">63bd81942d9e0906706d642d</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Dario Di Cillo ]]>
                </dc:creator>
                <pubDate>Thu, 19 Jan 2023 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/01/java-scanner-nextline-call-gets-skipped-solved.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/java-scanner-nextline-call-gets-skipped-solved/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Java scanner.nextLine() Method Call Gets Skipped Error [SOLVED]</a>
      </p><p>C'è un errore che spesso disorienta i nuovi programmatori Java. Si verifica quando una serie di prompt di input vengono raggruppati insieme e una delle chiamate del metodo <code>scanner.nextLine()</code> viene saltata – senza alcuna traccia di errore.</p><p>Dai un'occhiata al seguente snippet, ad esempio:</p><pre><code class="language-java">import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("Come ti chiami? ");
        String name = scanner.nextLine();

        System.out.printf("Ciao %s. Quanti anni hai? ", name);
        int age = scanner.nextInt();

        System.out.printf("Bene! %d anni sono un'ottima età per imparare a programmare. \nChe linguaggio preferisci? ", age);
        String language = scanner.nextLine();

        System.out.printf("Ah! %s è un linguaggio di programmazione molto valido.", language);

        scanner.close();

    }

}
</code></pre><p>La prima chiamata <code>scanner.nextLine()</code> chiede all'utente il suo nome. Poi la chiamata <code>scanner.nextInt()</code> chiede all'utente la sua età. L'ultima chiamata <code>scanner.nextLine()</code> chiede all'utente il suo linguaggio di programmazione preferito. Infine chiudi l'oggetto scanner e la finisci qui.</p><p>Si tratta di codice Java molto semplice, che fa uso di un oggetto <code>scanner</code> per prendere un input dall'utente. Proviamo a eseguire il programma e vediamo cosa accade.</p><p>Se hai eseguito il programma, probabilmente hai notato che chiede il nome, l'età e poi salta l'ultima richiesta di input per il linguaggio di programmazione preferito, terminando di colpo. Ecco quello che andremo a risolvere oggi.</p><h2 id="perch-la-chiamata-scanner-nextline-viene-saltata-dopo-la-chiamata-scanner-nextint-"><strong>Perché la chiamata <code>scanner.nextLine()</code> viene saltata dopo la chiamata <code>scanner.nextInt()</code>?</strong></h2><p>Questo comportamento non è limitato solo al metodo <code>scanner.nextInt()</code>. Se chiami il metodo <code>scanner.nextLine()</code> dopo uno qualsiasi dei metodi <code>scanner.nextQualcosa()</code>, il programma salterà quella chiamata.</p><p>Ciò ha a che fare con il modo in cui funzionano i due metodi. Il primo <code>scanner.nextLine()</code> richiede all'utente il suo nome.</p><p>Quando l'utente digita il suo nome e preme invio, <code>scanner.nextLine()</code> utilizza il nome e l'invio o il carattere nuova riga alla fine.</p><p>Questo vuol dire che il buffer degli input è attualmente vuoto. Quindi il metodo <code>scanner.nextInt()</code> chiede all'utente la sua età. L'utente la digita e preme invio.</p><p>A differenza del metodo <code>scanner.nextLine()</code>, il metodo <code>scanner.nextInt()</code> utilizza soltanto la parte intera e lascia l'invio o il carattere nuova riga nel buffer.</p><p>Quando viene chiamato lo <code>scanner.nextLine()</code> successivo, trova il carattere nuova riga ancora presente nel buffer degli input e lo interpreta erroneamente come l'input dell'utente.</p><p>Come puoi vedere, come molti altri problemi della vita reale, tutto ciò è causato da un'incomprensione tra l'utente e il programmatore.</p><p>Esistono due modi per risolvere il problema. Puoi utilizzare il carattere nuova riga dopo che avviene la chiamata di <code>scanner.nextInt()</code> oppure puoi prendere tutti gli input come stringhe per poi convertirli successivamente nei tipi di dato corretti.</p><h2 id="come-svuotare-il-buffer-degli-input-dopo-la-chiamata-scanner-nextint-"><strong>Come svuotare il buffer degli input dopo la chiamata <code>scanner.nextInt()</code></strong></h2><p>È più facile di quanto pensi. Tutto ciò che devi fare è aggiungere un'altra chiamata <code>scanner.nextLine()</code> dopo la chiamata <code>scanner.nextInt()</code>.</p><pre><code class="language-java">import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("Come ti chiami? ");
        String name = scanner.nextLine();

        System.out.printf("Ciao %s. Quanti anni hai? ", name);
        int age = scanner.nextInt();

        // utilizza il carattere nuova riga nel buffer
        scanner.nextLine();

        System.out.printf("Bene! %d anni sono un'ottima età per imparare a programmare. \nChe linguaggio preferisci? ", age);
        String language = scanner.nextLine();

        System.out.printf("Ah! %s è un linguaggio di programmazione molto valido.", language);

        scanner.close();

    }

}
</code></pre><p>Sebbene questa soluzione funzioni, occorre aggiungere una chiamata aggiuntiva <code>scanner.nextLine()</code> ogni volta che chiami uno degli altri metodi. Va bene per piccoli programmi, ma per programmi più complessi può degenerare molto in fretta.</p><h2 id="come-interpretare-gli-input-presi-usando-il-metodo-scanner-nextline-"><strong>Come interpretare gli input presi usando il metodo <code>scanner.nextLine()</code></strong></h2><p>Tutta la classe wrapper in Java contiene metodi per interpretare valori stringa. Ad esempio, il metodo <code>Integer.parseInt()</code> può interpretare un valore intero da una data stringa.</p><pre><code class="language-java">import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("Come ti chiami? ");
        String name = scanner.nextLine();

        System.out.printf("Ciao %s. Quanti anni hai? ", name);
        // interpreta l'intero dalla stringa
        int age = Integer.parseInt(scanner.nextLine());

        System.out.printf("Bene! %d anni sono un'ottima età per imparare a programmare. \nChe linguaggio preferisci? ", age);
        String language = scanner.nextLine();

        System.out.printf("Ah! %s è un linguaggio di programmazione molto valido.", language);

        scanner.close();

    }

}
</code></pre><p>Questo è un modo più pulito per combinare richieste di più tipi di input in Java. Finché fai attenzione a quello che l'utente sta inserendo, il parsing non dovrebbe dare problemi.</p><h2 id="conclusione"><strong><strong><strong>Conclusion</strong></strong>e</strong></h2><p>Grazie di cuore per interessarti a quello che scrivo. Spero che questo tutorial ti abbia aiutato in qualche modo.</p><p>Se lo hai trovato utile, condividilo con i tuoi amici. E se vuoi seguirmi, sono su <a href="https://twitter.com/frhnhsin">Twitter</a> e <a href="https://www.linkedin.com/in/farhanhasin/">LinkedIn</a>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Gli Operatori Java – &, && (AND) || (OR) Operatori Logici ]]>
                </title>
                <description>
                    <![CDATA[ Nella maggior parte dei linguaggi di programmazione si utilizzano gli operatori per eseguire operazioni sulle variabili.  Sono divisi in diverse categorie come gli operatori aritmetici, gli operatori di assegnamento, gli operatori logici e così via. In questo articolo parleremo dell'operatore bit a bit AND e degli operatori logici AND ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/gli-operatori-java/</link>
                <guid isPermaLink="false">63b4859ae612d50632ae9c9e</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniele Perottoni ]]>
                </dc:creator>
                <pubDate>Fri, 13 Jan 2023 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2023/01/logic-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/java-operator-and-or-logical-operators/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Java Operator – &amp;, &amp;&amp; (AND) || (OR) Logical Operators</a>
      </p><p>Nella maggior parte dei linguaggi di programmazione si utilizzano gli operatori per eseguire operazioni sulle variabili. </p><p>Sono divisi in diverse categorie come gli operatori aritmetici, gli operatori di assegnamento, gli operatori logici e così via.</p><p>In questo articolo parleremo dell'operatore bit a bit <strong><strong>AND</strong></strong> e degli operatori logici <strong><strong>AND </strong></strong>(<code>&amp;&amp;</code>) e <strong><strong>OR </strong></strong>(<code>||</code>).</p><h2 id="come-usare-l-operatore-bit-a-bit-and"><strong>Come usare l'operatore bit a bit <code>AND</code></strong></h2><p>Il simbolo <code>&amp;</code> indica l'operatore bit a bit <strong><strong>AND</strong></strong>. Valuta il valore binario dei numeri dati. Il risultato binario di questi numeri sarà restituito in base 10.</p><p>L'operatore <code>&amp;</code> inizia la sua operazione valutando il valore dei caratteri in entrambi i numeri partendo da sinistra.</p><p>Vediamo un esempio per capire meglio:</p><pre><code class="language-java">System.out.println(10 &amp; 12);
// ritorna 8</code></pre><p>Analizziamo i passaggi.</p><p>Il valore binario di 10 è 1010</p><p>Il valore binario di 12 è 1100</p><p>Prima di iniziare l'operazione, è necessario tenere a mente una cosa:</p><ul><li>1 and 0 =&gt; 0</li><li>0 and 1 =&gt; 0</li><li>1 and 1 =&gt; 1</li><li>0 and 0 =&gt; 0</li></ul><p>Eseguiamo quindi l'operazione.</p><p>Il primo carattere per 10 è 1 e il primo carattere per 12 è anch'esso 1, quindi:</p><p>1 and 1 = 1.</p><p>Passiamo ai successivi caratteri – 0 per 10 e 1 per 12:</p><p>1 and 0 = 0.</p><p>Per i terzi caratteri – 1 per 10 e 0 per 12:</p><p>1 and 0 = 0.</p><p>Per gli ultimi caratteri – 0 per 10 e 0 per 12:</p><p>0 and 0 = 0.</p><p>Ora combiniamo tutti i caratteri restituiti. Otterremo 1000.</p><p>Il valore binario 1000 in base 10 è 8 e questo è il motivo per cui la nostra operazione ha restituito 8.</p><h2 id="come-usare-l-operatore-logico-and"><strong>Come usare l'operatore logico <code>AND</code></strong></h2><p>Gli operatori logici vengono utilizzati per valutare le condizioni. Essi restituiscono <code>true</code> o <code>false</code> in base alle condizioni date.</p><p>Il simbolo <code>&amp;&amp;</code> indica l'operatore <strong><strong>AND</strong></strong>. Valuta due affermazioni/condizioni e restituisce true solo quando entrambe le affermazioni/condizioni sono vere.</p><p>Ecco come si presenta la sintassi:</p><pre><code class="language-txt">affermazione1/condizione1 &amp;&amp; affermazione1/condizione1</code></pre><p>Come puoi vedere qui sopra, ci sono due affermazioni/condizioni separate dall'operatore. L'operatore valuta il valore di entrambe le affermazioni/condizioni e ci restituisce un risultato: true o false.</p><p>Ecco un esempio:</p><pre><code class="language-java">System.out.println((10 &gt; 2) &amp;&amp; (8 &gt; 4));
//true</code></pre><p>L'operatore restituirà <code>true</code> perché entrambe le condizioni sono vere – 10 è maggiore di 2 <strong><strong>and </strong></strong>8 è maggiore di 4. Se una delle due condizioni avesse una logica non vera, otterremmo <code>false</code>.</p><p>Per comprendere meglio l'operatore <code>&amp;&amp;</code>, è necessario sapere che entrambe le condizioni devono essere vere per ottenere il valore <code>true</code>.</p><p>Ecco un altro esempio che ritorna <code>false</code>:</p><pre><code class="language-java">System.out.println((2 &gt; 10) &amp;&amp; (8 &gt; 4));
// false</code></pre><p>In questo caso, 2 non è maggiore di 10, ma 8 è maggiore di 4 - quindi ci viene restituito <code>false</code>. Questo perché una delle condizioni non è vera.</p><ul><li>Se entrambe le condizioni sono vere =&gt; <code>true</code></li><li>Se una delle due condizioni è falsa =&gt; <code>false</code></li><li>Se entrambe le condizioni sono false =&gt; <code>false</code></li></ul><h2 id="come-usare-l-operatore-logico-or"><strong>Come usare l'operatore logico <code>OR</code></strong></h2><p>Si utilizza il simbolo <code>||</code> per indicare l'operatore <strong><strong>OR</strong></strong>. Questo operatore restituisce <code>false</code> solo quando entrambe le condizioni sono false. Ciò significa che se entrambe le condizioni sono vere, si otterrà il valore <code>true</code>, e se una delle due condizioni è vera, si otterrà comunque il valore <code>true</code>.</p><p>Ecco la sintassi:</p><pre><code class="language-txt">affermazione1/condizione1 || affermazione1/condizione1</code></pre><p>Vediamo alcuni esempi.</p><pre><code>System.out.println((6 &lt; 1) || (4 &gt; 2));  
// true</code></pre><p>Restituisce <code>true</code> perché una delle condizioni è vera.</p><ul><li>Se entrambe le condizioni sono vere =&gt; <code>true</code></li><li>Se una delle condizioni è vera =&gt; <code>true</code></li><li>Se entrambe le condizioni sono false =&gt; <code>false</code></li></ul><h2 id="conclusioni"><strong>Conclusioni</strong></h2><p>In questo articolo abbiamo appreso come utilizzare l'operatore bit a bit <code>&amp;</code> in Java e come viene eseguita l'operazione per ottenere un risultato.</p><p>Abbiamo anche imparato a utilizzare gli operatori logici <strong><strong><code>&amp;&amp;</code> </strong></strong>e <strong><strong><code>||</code></strong> </strong>in Java. Abbiamo imparato quale valore restituisce ciascuna operazione in base alle condizioni coinvolte nel calcolo.</p><p>Buona programmazione!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Tutorial JVM - L'Architettura della Java Virtual Machine Spiegata per Principianti ]]>
                </title>
                <description>
                    <![CDATA[ Che tu sia solito sviluppare programmi in Java oppure no, a un certo punto potresti aver sentito parlare di Java Virtual Machine (JVM). La JVM è il fulcro dell'ecosistema Java e rende possibile per i programmi basati su Java di seguire l'approccio "write once, run anywhere" (ovvero scrivi una volta ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/tutorial-jvm-larchitettura-della-java-virtual-machine-spiegata-per-principianti/</link>
                <guid isPermaLink="false">6371f49c431671062c019e33</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Dario Di Cillo ]]>
                </dc:creator>
                <pubDate>Mon, 28 Nov 2022 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2022/11/JVM.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/jvm-tutorial-java-virtual-machine-architecture-explained-for-beginners/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">JVM Tutorial - Java Virtual Machine Architecture Explained for Beginners</a>
      </p><p>Che tu sia solito sviluppare programmi in Java oppure no, a un certo punto potresti aver sentito parlare di Java Virtual Machine (JVM).</p><p>La JVM è il fulcro dell'ecosistema Java e rende possibile per i programmi basati su Java di seguire l'approccio <em><em>"write once, run anywhere"</em> (</em>ovvero scrivi una volta ed esegui ovunque). Puoi scrivere del codice Java su una macchina ed eseguirlo su qualsiasi altra macchina che utilizza la JVM.</p><p>La JVM è stata inizialmente progettata per supportare soltanto Java. Tuttavia, nel tempo, altri linguaggi come Scala, Kotlin e Groovy sono stati adottati sulla piattaforma Java. Tutti questi linguaggi sono collettivamente conosciuti come linguaggi JVM.</p><p>In questo articolo, impareremo di più a riguardo della JVM, il suo funzionamento e i vari componenti di cui è costituita.</p><h1 id="cos-una-macchina-virtuale"><strong>Cos'è una macchina virtuale?</strong></h1><p>Prima di passare alla JVM, esaminiamo il concetto di macchina virtuale (virtual machine, VM).</p><p>Una macchina virtuale è una <em>rappresentazione virtuale di un computer fisico</em>. La macchina virtuale può essere chiamata macchina <em>guest</em>, e il computer fisico su cui gira la macchina virtuale può essere detto macchina <em>host</em>. </p><blockquote>N.d.T.<br>Dall'inglese host, chi offre ospitalità, e guest, chi ne usufruisce.</blockquote><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-37.png" class="kg-image" alt="image-37" width="600" height="400" loading="lazy"></figure><p>Una singola macchina fisica può ospitare più macchine virtuali, ognuna con il proprio sistema operativo e le proprie applicazioni, e ognuna isolata dalle altre.</p><h1 id="cos-la-java-virtual-machine"><strong>Cos'è la Java Virtual Machine?</strong></h1><p>Nei linguaggi di programmazione come C e C++, il codice viene prima compilato in codice macchina specifico per una piattaforma. Questi linguaggi sono detti <em>compilati</em>.</p><p>D'altro canto, nei linguaggi come JavaScript e Python, il computer esegue le istruzioni direttamente senza doverli compilare. Questi linguaggi sono detti <em>interpretati</em>.</p><p>Java utilizza una combinazione di entrambe le tecniche. Il codice Java viene prima compilato in bytecode per generare un file <em>class</em>, che viene poi interpretato dalla Java Virtual Machine per la piattaforma sottostante. Lo stesso file <em>class </em>può essere eseguito su qualsiasi versione della JVM in esecuzione su su qualsiasi piattaforma e sistema operativo.</p><p><em>Come le macchine virtuali</em>, la JVM crea uno spazio isolato su una macchina host. Questo spazio può essere usato per eseguire i programmi Java indipendentemente dalla piattaforma o dal sistema operativo della macchina.</p><h1 id="architettura-della-java-virtual-machine"><strong>Architettura della Java Virtual Machine</strong></h1><p>La JVM consiste di tre componenti distinti:</p><ol><li>Class Loader</li><li>Memoria di runtime/area dati</li><li>Execution Engine</li></ol><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-39.png" class="kg-image" alt="image-39" width="600" height="400" loading="lazy"></figure><p>Diamo un'occhiata a ognuno di loro più nel dettaglio.</p><h2 id="class-loader"><strong>Class Loader</strong></h2><p>Quando compili un file sorgente <code>.java</code>, questo viene convertito in bytecode come un file <code>.class</code>. Quando provi a utilizzare questa classe in un programma, il class loader la carica nella memoria principale.</p><p>La prima classe ad essere caricata nella memoria è solitamente la classe che contiene il metodo <code>main()</code>.</p><p>Esistono tre fasi nel processo di caricamento della classe: caricamento (loading), collegamento (linking) e inizializzazione (initialization).</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-40.png" class="kg-image" alt="image-40" width="600" height="400" loading="lazy"></figure><h3 id="caricamento"><strong>Caricamento</strong></h3><p>Il processo di caricamento comporta prendere la rappresentazione binaria (bytecode) di una classe o interfaccia con un particolare nome, e da essa generare la classe originaria o interfaccia.</p><p>Esistono tre class loader integrati disponibili in Java:</p><ul><li><strong><strong>Bootstrap Class Loader</strong></strong> <strong><strong>-</strong></strong> Questo è il class loader radice. Si tratta di una superclasse dell'Extension Class Loader e carica i pacchetti standard Java come <code>java.lang</code>, <code>java.net</code>, <code>java.util</code>, <code>java.io</code> e via dicendo. Questi pacchetti sono presenti all'interno del file <code>rt.jar</code> e altre librerie di base presenti nella cartella <code>$JAVA_HOME/jre/lib</code>.</li><li><strong><strong>Extension Class Loader -</strong></strong> È una sottoclasse del Bootstrap Class Loader e superclasse dell'Application Class Loader. Si occupa del caricamento delle librerie standard Java che sono presenti nella cartella <code>$JAVA_HOME/jre/lib/ext</code>.</li><li><strong><strong>Application Class Loader -</strong></strong> È l'ultimo class loader e sottoclasse dell'Extension Class Loader. Carica i file presenti nel classpath. Per impostazione predefinita, il classpath è regolato sulla cartella corrente dell'applicazione. Il classpath può anche essere modificato aggiungendo le opzioni da riga di comando <code>-classpath</code> o <code>-cp</code>.</li></ul><p>La JVM utilizza il metodo <code>ClassLoader.loadClass()</code> per caricare la classe nella memoria. Tenta di caricare la classe sulla base di un nome pienamente abilitato.</p><p>Se il class loader genitore non è in grado di trovare una classe, delega il lavoro al class loader figlio. Se l'ultimo class loader figlio non è in grado di caricare la classe restituisce <code>NoClassDefFoundError</code> o <code>ClassNotFoundException</code><em><em>.</em></em></p><h3 id="collegamento"><strong>Collegamento</strong></h3><p>Dopo che una classe viene caricata in memoria, viene sottoposta al processo di collegamento. Collegare una classe o un'interfaccia implica collegare insieme i diversi elementi e dipendenze del programma.</p><p>Il collegamento comprende i seguenti passaggi:</p><p><strong><strong>Verifica</strong></strong>: questa fase controlla la correttezza strutturale del file <code>.class</code> facendo un confronto con un insieme di vincoli o regole. Se la verifica fallisce per qualche ragione, otteniamo <code>VerifyException</code>.</p><p>Ad esempio, se il codice è stato creato usando Java 11, ma viene eseguito su un sistema che ha installato Java 8, la fase di verifica fallirà.</p><p><strong><strong>Prepara</strong>z<strong>ion</strong>e</strong>: in questa fase, la JVM alloca la memoria per i campi statici di una classe o un'interfaccia e li inizializza con dei valori predefiniti.</p><p>Ad esempio, supponi di aver già dichiarato la seguente variabile nella tua classe:</p><pre><code class="language-java">private static final boolean enabled = true;</code></pre><p>Durante la &nbsp;fase di preparazione, la JVM alloca memoria per la variabile <code>enabled</code> e imposta il suo valore su quello predefinito per un booleano, ovvero <code>false</code>.</p><p><strong><strong>R</strong>isoluzione</strong>: in questa fase, i riferimenti simbolici vengono sostituiti con riferimenti diretti al constant pool nel runtime.</p><p>Ad esempio, se ci sono riferimenti ad altre classi o variabili costanti presenti in altre classe, sono risolti durante questa fase e rimpiazzati con i riferimenti attuali.</p><h3 id="inizializzazione"><strong>Inizializzazione</strong></h3><p>L'inizializzazione comporta l'esecuzione del metodo di inizializzazione della classe o dell'interfaccia (conosciuto come <code>&lt;clinit&gt;</code>). Ciò può comprendere la chiamata del costruttore della classe, eseguendo il blocco statico e assegnando i valori a tutti le variabili statiche. Questo è il passaggio finale del caricamento di una classe.</p><p>Ad esempio, prima, quando abbiamo dichiarato il seguente codice:</p><pre><code class="language-java">private static final boolean enabled = true;</code></pre><p>La variabile <code>enabled</code> era impostata al suo valore predefinito, <code>false</code>, durante la fase di preparazione. Nella fase di inizializzazione, alla variabile è assegnato il suo valore reale, <code>true</code>.</p><p><strong><strong>Not</strong>a</strong>: la JVM è multi-thread. Può capitare che più thread tentino di inizializzare la stessa classe allo stesso tempo. Ciò può portare a problemi di concorrenza. Occorre gestire la sicurezza del thread per assicurare che il programma funzioni in modo appropriato in un ambiente multi-thread.</p><h2 id="area-dati-di-runtime"><strong>Area dati di runtime</strong></h2><p>Esistono cinque componenti all'interno dell'area dati di runtime:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-32.png" class="kg-image" alt="image-32" width="600" height="400" loading="lazy"></figure><p>Analizziamoli individualmente.</p><h3 id="area-dei-metodi"><strong>Area dei metodi</strong></h3><p>Tutti i dati di livello classe come i dati di constant pool, campo e metodo, e il codice per metodi e costruttori sono conservati qui.</p><p>Se la memoria disponibile nell'area dei metodi non è sufficiente per l'avvio del programma, la JVM restituisce <code>OutOfMemoryError</code>.</p><p>Ad esempio, supponi di avere la seguente definizione di classe:</p><pre><code class="language-java">public class Employee {
  
  private String name;
  private int age;
  
  public Employee(String name, int age) {
  
    this.name = name;
    this.age = age;
  }
}</code></pre><p>In questo codice di esempio, il dato al livello del campo come <code>name</code> e <code>age</code> e i dettagli del costruttore sono caricati nell'area dei metodi.</p><p>L'area dei metodi è creata all'avvio della macchina virtuale e ce n'è una sola per JVM.</p><h3 id="area-di-heap"><strong>Area di heap</strong></h3><p>Tutti gli oggetti e le loro corrispondenti variabili di istanza sono memorizzati qui. Questa è l'area di dati di run-time dalla quale è allocata la memoria per tutte le istanze di classe e array.</p><p>Ad esempio, supponi di dichiarare la seguente istanza:</p><pre><code class="language-java">Employee employee = new Employee();</code></pre><p>In questo esempio di codice, viene creata un'istanza di <code>Employee</code> e caricata nell'area heap.</p><p>L'area di heap è creata all'avvio della macchina virtuale e ce n'è una sola per JVM.</p><p><strong><strong>Not</strong>a</strong>: dato che l'area dei metodi e l'heap condividono la stessa memoria per thread multipli, i dati memorizzati qui non sono thread-safe.</p><h3 id="stack"><strong>Stack</strong></h3><p>Ogniqualvolta un nuovo thread viene creato nella JVM, viene creato contemporaneamente uno stack di runtime separato. Tutte le variabili locali, le chiamate di metodi e i risultati parziali sono memorizzati nell'area di stack.</p><p>Se l'elaborazione fatta in un thread richiede una dimensione di stack maggiore di quella disponibile, la JVM restituisce <code>StackOverflowError</code>.</p><p>Per ogni chiamata di un metodo, viene creata un'entrata nella memoria di stack, chiamata frame dello stack. Quando la chiamata del metodo è completa, il frame dello stack viene eliminato.</p><p>Un frame dello stack è diviso in tre sottoparti:</p><ul><li><strong>Variabili locali<strong> –</strong></strong> Ogni frame contiene un array di variabili conosciuto come <em>variabili locali</em>. Tutte le variabili locali e i loro valori sono memorizzati qui. La lunghezza di questo array è determinata al tempo di compilazione.</li><li><strong><strong>Stack </strong>degli operandi <strong>–</strong></strong> Ogni frame contiene uno stack LIFO (last-in-first-out) conosciuto come <em>stack degli operandi</em>. Agisce come spazio di lavoro di runtime per svolgere qualsiasi operazione intermedia. La massima profondità di questo stack è determinata al tempo di compilazione.</li><li><strong><strong>Frame Data – </strong></strong>Tutti i simboli corrispondenti ai metodi sono memorizzati qui. Contiene anche le informazioni sui blocchi catch in caso di eccezioni.</li></ul><p>Ad esempio, supponi di avere il seguente codice:</p><pre><code class="language-java">double calculateNormalisedScore(List&lt;Answer&gt; answers) {
  
  double score = getScore(answers);
  return normalizeScore(score);
}

double normalizeScore(double score) {
  
  return (score – minScore) / (maxScore – minScore);
}
</code></pre><p>In questo esempio di codice, le variabili come <code>answers</code> e <code>score</code> sono posizionate nell'array delle variabili locali. Lo stack degli operandi contiene le variabili e gli operatori richiesti per svolgere i calcoli matematici di sottrazione e divisione.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-36.png" class="kg-image" alt="image-36" width="600" height="400" loading="lazy"></figure><p><strong><strong>Not</strong>a</strong>: dato che l'area di stack non è condivisa, è totalmente thread-safe.</p><h3 id="registri-program-counter-pc-"><strong>Registri Program Counter (PC)</strong></h3><p>La JVM supporta più thread allo stesso tempo. Ogni thread ha il suo registro PC per contenere l'indirizzo dell'istruzione JVM attualmente in esecuzione. Una volta che l'istruzione è eseguita, il registro PC viene aggiornato con l'istruzione successiva.</p><h3 id="stack-dei-metodi-nativi"><strong>Stack dei metodi nativi</strong></h3><p>La JVM contiene degli stack che supportano metodi <em>nativi</em>. Questi metodi sono scritti in altri linguaggio diverso da Java, come C e C++. Per ogni nuovo thread, viene allocato uno stack separato per un metodo nativo.</p><h2 id="execution-engine"><strong>Execution Engine</strong></h2><p>Una volta che il bytecode è stato caricato nella memoria principale e i dettagli sono disponibili nell'area dati di runtime, il passo successivo è eseguire il programma. L'execution engine si occupa di eseguire il codice presente in ogni classe.</p><p>Tuttavia, prima di eseguire il programma, il bytecode deve essere convertito in istruzioni in linguaggio macchina. La JVM può usare un interprete o un compilatore JIT per l'execution engine.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2021/01/image-33.png" class="kg-image" alt="image-33" width="600" height="400" loading="lazy"></figure><h3 id="interprete"><strong>Interprete</strong></h3><p>L'interprete legge ed esegue le istruzioni del bytecode riga per riga. A causa dell'esecuzione riga per riga, l'interprete è relativamente più lento.</p><p>Un altro svantaggio dell'interprete è che quando un metodo viene chiamato più volte, è necessaria una nuova interpretazione ogni volta.</p><h3 id="compilatore-jit"><strong>Compilatore JIT</strong></h3><p>Il compilatore JIT rimedia allo svantaggio dell'interprete. L'execution engine utilizza prima l'interprete per eseguire il bytecode, ma quando trova del codice ripetuto, utilizza il compilatore JIT.</p><p>Il compilatore JIT poi compila l'intero bytecode e lo modifica in codice macchina nativo, che viene usato direttamente per chiamate di metodi ripetute, che migliorano le prestazioni del sistema.</p><p>Il compilatore JIT ha i seguenti componenti:</p><ol><li><strong><strong>Intermediate Code Generator -</strong></strong> genera il codice intermedio</li><li><strong><strong>Code Optimizer -</strong></strong> ottimizza il codice intermedio per ottenere delle prestazioni migliori</li><li><strong><strong>Target Code Generator -</strong></strong> converte il codice intermedio in codice macchina nativo</li><li><strong><strong>Profiler -</strong></strong> trova gli hotspot (codice che viene eseguito ripetutamente)</li></ol><p>Per capire meglio la differenza tra l'interprete &nbsp;e in compilatore JIT, supponi di avere il seguente codice:</p><pre><code class="language-java">int sum = 10;
for(int i = 0 ; i &lt;= 10; i++) {
   sum += i;
}
System.out.println(sum);</code></pre><p>Un interprete recupera dalla memoria il valore di <code>sum</code> per ogni iterazione del loop, gli aggiunge il valore di <code>i</code> e scrive nella memoria. Si tratta di un'operazione dispendiosa, in quanto accede alla memoria ogni volta che entra nel loop.</p><p>Tuttavia, il compilatore JIT riconosce che questo codice ha un hot spot ed esegue delle ottimizzazioni. Conserva una copia locale di <code>sum</code> nel registro PC per il thread e continua ad aggiungervi il valore di <code>i</code> nel loop. Una volta che il loop è completato, scrive il valore di <code>sum</code> in memoria.</p><p><strong><strong>Not</strong>a</strong>: un compilatore JIT impiega più tempo a compilare il codice rispetto a quello necessario all'interprete per interpretare il codice riga per riga. Se ti occorre eseguire un programma solo una volta, è meglio usare l'interprete.</p><h3 id="garbage-collector"><strong>Garbage Collector</strong></h3><p>Il Garbage Collector (GC) raccoglie e rimuove gli oggetti non referenziati dall'area di heap. Si tratta del processo di recuperare la memoria di runtime inutilizzata, eliminandoli.</p><p>Questo processo rende efficiente la memoria di Java, perché rimuove gli oggetti non referenziati dalla memoria heap e crea spazio per nuovi oggetti. Consta di due fasi:</p><ol><li><strong><strong>Mark -</strong></strong> in questo passaggio, il GC identifica gli oggetti inutilizzati in memoria</li><li><strong><strong>Sweep -</strong></strong> in questo passaggio, il GC rimuove gli oggetti identificati durante la fase precedente</li></ol><p>Il processo di raccolta è svolto automaticamente dalla JVM a intervalli regolari e non necessita di essere gestito separatamente. Può essere anche innescato dalla chiamata <code>System.gc()</code>, ma l'esecuzione non è garantita.</p><p>La JVM contiene 3 tipi differenti di garbage collector:</p><ol><li><strong><strong>Serial GC -</strong></strong> Questa è l'implementazione più semplice di GC ed è progettata per piccole applicazioni in esecuzione su ambienti mono-thread. Utilizza un solo thread per raccolta. Quando viene eseguito, porta a un evento "stop the world", in cui l'intera applicazione viene messa in pausa. L'argomento JVM per usare il Serial Garbage Collector è <code>-XX:+UseSerialGC</code></li><li><strong><strong>Parallel GC - </strong></strong>Questa è l'implementazione predefinita di GC nella JVM, conosciuta anche come Throughput Collector. Utilizza più thread per raccolta, ma mette comunque in pausa l'applicazione quando viene eseguito. L'argomento JVM per usare il Parallel Garbage Collector è <code>-XX:+UseParallelGC</code>.</li><li><strong><strong>Garbage First (G1) GC -</strong></strong> G1GC è stato progettato per applicazioni multi-thread che hanno disponibili una grande dimensione dell'heap (più di 4 GB). Ripartisce l'heap in un set di regioni di uguale dimensione e usa thread multipli per scansionarle. G1GC identifica le regioni più ricche di elementi non più referenziati e inizia da queste a svolgere la raccolta. L'argomento JVM per usare G1GC è &nbsp;<code>-XX:+UseG1GC</code></li></ol><p><strong><strong>Not</strong>a</strong>: esiste un altro tipo di garbage collector chiamato <strong><strong>Concurrent Mark Sweep (CMS) GC</strong></strong>. Tuttavia, è obsoleto fin da Java 9 e completamente rimosso in Java 14 in favore di G1GC.</p><h2 id="java-native-interface-jni-"><strong>Java Native Interface (JNI)</strong></h2><p>Delle volte, è necessario usare del codice nativo (non Java), ad esempio C/C++. Potrebbe essere nel caso in cui dobbiamo interagire con l'hardware, oppure per ovviare ai vincoli di Java sulla gestione della memoria e le prestazioni. Java supporta l'esecuzione del codice nativo tramite la Java Native Interface (JNI).</p><p>La JNI agisce come un ponte per consentire il supporto di pacchetti per altri linguaggi di programmazione come C, C++ e via dicendo. Ciò è particolarmente utile nei casi in cui ti occorre scrivere del codice non interamente supportato da Java, come delle specifiche funzionalità di alcune piattaforme che possono essere scritte solo in C.</p><p>Puoi usare la parola chiave <code>native</code> per indicare che l'implementazione del metodo sarà fornita in una libreria nativa. Avrai anche bisogno di invocare <code>System.loadLibrary()</code> per caricare in memoria la libreria nativa condivisa e rendere le sue funzioni disponibili in Java.</p><h2 id="librerie-di-metodi-nativi"><strong>Librerie di metodi nativi</strong></h2><p>Le librerie di metodi nativi sono librerie scritte in altri linguaggi di programmazione, come C, C++ e assembly. Queste librerie sono solitamente presenti in forma di file <code>.dll</code> o <code>.so</code>, e possono essere caricateattraverso il JNI.</p><h1 id="errori-comuni-jvm"><strong>Errori comuni JVM</strong></h1><ul><li><strong><strong>ClassNotFoundExcecption</strong></strong> - Si verifica quando il class loader sta cercando di caricare delle classi usando <code>Class.forName()</code>, <code>ClassLoader.loadClass()</code> o <code>ClassLoader.findSystemClass()</code> ma non viene trovata nessuna definizione per il nome della classe specificato.</li><li><strong><strong>NoClassDefFoundError</strong></strong> - Si verifica quando un compilatore compila con successo la classe, ma il class loader non è in grado di individuare il file class durante il runtime.</li><li><strong><strong>OutOfMemoryError</strong></strong> - Si verifica quando la JVM non può allocare un oggetto perché non c'è memoria, e non è possibile liberare altra memoria tramite il garbage collector.</li><li><strong><strong>StackOverflowError</strong></strong> - Si verifica quando la JVM esaurisce la memoria creando un nuovo frame dello stack processando un thread.</li></ul><h1 id="conclusione"><strong>Conclusione</strong></h1><p>In questo articolo, abbiamo discusso l'architettura della Java Virtual Machine e i suoi diversi componenti. Spesso non scaviamo a fondo nella meccanica interna della JVM o non ci interessiamo a come funziona mentre il nostro codice è all'opera.</p><p>È soltanto quando qualcosa va storto e abbiamo bisogno di ottimizzare la JVM o sistemare un problema di memoria che proviamo a capire la sua meccanica interna.</p><p>Questa è anche una domanda molto comune durante i colloqui di lavoro, sia al livello junior che senior per le posizioni backend. Una conoscenza approfondita della JVM ti aiuta a scrivere del codice migliore e a evitare le insidie collegate agli errori di stack e di memoria.</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.178026315789474%;" class="fluid-width-video-wrapper">
            <iframe src="https://www.youtube.com/embed/jnpuRvRdTgI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" title="Embedded content" loading="lazy" name="fitvid0" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 22px; vertical-align: middle; position: absolute; top: 0px; left: 0px; width: 760px; height: 426.953px;"></iframe>
          </div>
        </div>
      </figure><p>Grazie per essere rimasto con me fino a questo punto. Spero che questo articolo ti sia piaciuto. Puoi connetterti con me su <a href="https://www.linkedin.com/in/theawesomenayak/">LinkedIn</a>, dove discuto abitualmente di vita e tecnologia. Dai anche un'occhiata <a href="https://www.freecodecamp.org/news/author/theawesomenayak/">ai miei altri articoli</a> e al mio <a href="https://www.youtube.com/channel/UCmWAaPgfWAkl-Jep5mY-NNg?sub_confirmation=1">canale YouTube</a> (risorse in lingua originale inglese). Buona lettura. 🙂</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Il Manuale Java – Programmazione in Java per Principianti ]]>
                </title>
                <description>
                    <![CDATA[ Java è in circolazione dagli anni '90 e nonostante il suo grande successo in molti settori, questo linguaggio di programmazione multi-piattaforma e orientato agli oggetti, è spesso criticato. Indipendentemente da ciò che le persone pensano riguardo a Java, per la mia esperienza, posso dirti che è un eccellente linguaggio di ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/il-manuale-java-programmazione-in-java-per-principianti/</link>
                <guid isPermaLink="false">632894cff91c6d07327f7753</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Dario Di Cillo ]]>
                </dc:creator>
                <pubDate>Mon, 10 Oct 2022 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2022/09/The-Java-Handbook.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/the-java-handbook/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The Java Handbook – Learn Java Programming for Beginners</a>
      </p><p>Java è in circolazione dagli anni '90 e nonostante il suo grande successo in molti settori, questo linguaggio di programmazione multi-piattaforma e orientato agli oggetti, è spesso criticato.</p><p>Indipendentemente da ciò che le persone pensano riguardo a Java, per la mia esperienza, posso dirti che è un eccellente linguaggio di programmazione. La sua prima apparizione risale al 1995, ed è ancora ampiamente usato – ed è probabile che questo non cambi a breve.</p><p>Puoi usare Java per costruire server, creare applicazioni desktop, giochi, applicazioni mobile e molto altro. Esistono anche altri linguaggi JVM (discuteremo a breve di cosa vuol dire) come <a href="https://kotlinlang.org/">Kotlin</a>, <a href="https://groovy-lang.org/">Groovy</a>, <a href="https://www.scala-lang.org/">Scala</a> e <a href="https://clojure.org/">Clojure</a> che puoi usare per diversi scopi.</p><p>Java è multi-piattaforma, che vuol dire che il codice che scrivi e compili su una piattaforma può essere eseguito su qualsiasi altra piattaforma che ha Java installato. Discuteremo questo tema in maggiore dettaglio più avanti.</p><p>Per ora, posso dirti che sebbene Java abbia i suoi difetti, ha anche tanto da offrire.</p><h2 id="sommario"><strong>Sommario</strong></h2><!--kg-card-begin: markdown--><ol>
<li><a href="#prerequisiti">Prerequisiti</a></li>
<li><a href="#come-scrivere-hello-world-in-java">Hello World</a>
<ol>
<li><a href="#cosa-succede-nel-codice">Cosa succede nel codice?</a></li>
<li><a href="#cos-la-jvm">JVM</a></li>
<li><a href="#cosa-sono-jre-e-jdk">JRE e JDK</a></li>
</ol>
</li>
<li><a href="#come-configurare-java-sul-tuo-computer">Configurare Java</a></li>
<li><a href="#come-installare-un-ide-java-sul-tuo-computer">Installare un IDE</a></li>
<li><a href="#come-creare-un-nuovo-progetto-su-intellij-idea">Creare un nuovo progetto su IntelliJ IDEA</a></li>
<li><a href="#come-lavorare-con-le-variabili-in-java">Variabili</a>
<ol>
<li><a href="#quali-sono-le-regole-per-dichiarare-le-variabili">Regole per dichiarare le variabili</a></li>
<li><a href="#cosa-sono-le-variabili-final">Variabili final</a></li>
</ol>
</li>
<li><a href="#quali-sono-i-tipi-di-dati-primitivi-in-java">Tipi di dati primitivi</a>
<ol>
<li><a href="#cos-una-conversione-di-tipo-o-casting">Conversione di tipo</a></li>
<li><a href="#cosa-sono-le-classi-wrapper-in-java">Classi wrapper</a></li>
</ol>
</li>
<li><a href="#come-usare-gli-operatori-in-java">Operatori</a>
<ol>
<li><a href="#cosa-sono-gli-operatori-aritmetici">Operatori aritmetici</a></li>
<li><a href="#cosa-sono-gli-operatori-di-assegnazione">Operatori di assegnazione</a></li>
<li><a href="#cosa-sono-gli-operatori-di-confronto">Operatori di confronto</a></li>
<li><a href="#cosa-sono-gli-operatori-logici">Operatori logici</a></li>
<li><a href="#cosa-sono-gli-operatori-unari">Operatori unari</a></li>
</ol>
</li>
<li><a href="#come-usare-le-stringhe-in-java">Stringhe</a>
<ol>
<li><a href="#come-formattare-una-stringa">Formattare una stringa</a></li>
<li><a href="#come-ottenere-la-lunghezza-di-una-stringa-e-verificare-se-una-stringa-vuota">Ottenere la lunghezza di una stringa e verificare se è vuota</a></li>
<li><a href="#come-dividere-e-unire-delle-stringhe">Dividere e unire stringhe</a></li>
<li><a href="#come-convertire-una-stringa-in-maiuscolo-o-minuscolo">Convertire una stringa in maiuscolo o minuscolo</a></li>
<li><a href="#come-confrontare-due-stringhe">Confrontare due stringhe</a></li>
<li><a href="#come-sostituire-caratteri-o-sottostringhe-in-una-stringa">Sostituire caratteri e sottostringhe</a></li>
<li><a href="#come-verificare-se-una-stringa-contiene-una-sottostringa">Verificare se una stringa contiene una sottostringa</a></li>
</ol>
</li>
<li><a href="#quali-sono-i-diversi-modi-di-inserire-input-e-ottenere-output-di-dati">Input e output</a></li>
<li><a href="#come-usare-le-istruzioni-condizionali-in-java">Istruzioni condizionali</a></li>
<li><a href="#cos-un-istruzione-switch-case">Istruzione switch-case</a></li>
<li><a href="#cos-la-visibilit-di-una-variabile-in-java">Visibilità delle variabili</a></li>
<li><a href="#quali-sono-i-valori-di-default-di-una-variabile-in-java">Valori predefiniti delle variabili</a></li>
<li><a href="#come-lavorare-con-gli-array-in-java">Array</a>
<ol>
<li><a href="#come-ordinare-un-array">Ordinare un array</a></li>
<li><a href="#come-eseguire-una-ricerca-binaria-su-un-array">Ricerca binaria su un array</a></li>
<li><a href="#come-riempire-un-array">Riempire un array</a></li>
<li><a href="#come-fare-una-copia-di-un-array">Copiare un array</a></li>
<li><a href="#come-confrontare-due-array">Confrontare due array</a></li>
</ol>
</li>
<li><a href="#come-usare-i-loop-in-java">Loop</a>
<ol>
<li><a href="#loop-for">Loop for</a></li>
<li><a href="#loop-for-each">Loop for-each</a></li>
<li><a href="#loop-while">Loop while</a></li>
<li><a href="#loop-do-while">Loop do-while</a></li>
</ol>
</li>
<li><a href="#come-lavorare-con-gli-arraylist-in-java">ArrayList</a>
<ol>
<li><a href="#come-aggiungere-o-rimuovere-elementi-multipli">Aggiungere o rimuovere elementi multipli</a></li>
<li><a href="#come-rimuovere-elementi-in-base-a-una-condizione">Rimuovere elementi in base a una condizione</a></li>
<li><a href="#come-clonare-e-confrontare-degli-arraylist">Clonare e confrontare ArrayList</a></li>
<li><a href="#come-verificare-la-presenza-di-un-elemento-e-se-un-arraylist-vuoto">Verificare le presenza di un elemento e se un ArrayList è vuoto</a></li>
<li><a href="#come-ordinare-un-arraylist">Ordinare un ArrayList</a></li>
<li><a href="#come-tenere-gli-elementi-comuni-in-due-arraylist">Tenere gli elementi comuni in due ArrayList</a></li>
<li><a href="#come-eseguire-un-azione-su-tutti-gli-elementi-di-un-arraylist">Eseguire un'azione su tutti gli elementi di un ArrayList</a></li>
</ol>
</li>
<li><a href="#come-lavorare-con-le-hashmap-in-java">HashMap</a>
<ol>
<li><a href="#come-inserire-o-sostituire-elementi-multipli-in-una-hashmap">Inserire e sostituire elementi multipli</a></li>
<li><a href="#come-verificare-se-una-hash-map-contiene-un-elemento-o-vuota">Verificare se un elemento è presente e se una HashMap è vuota</a></li>
<li><a href="#come-eseguire-un-azione-su-tutti-gli-elementi-di-una-hashmap">Eseguire un'azione su tutti gli elementi di una HashMap</a></li>
</ol>
</li>
<li><a href="#classi-e-oggetti-in-java">Classi e oggetti</a>
<ol>
<li><a href="#cos-un-metodo">Metodi</a></li>
<li><a href="#cos-l-overloading-dei-metodi">Overloading dei metodi</a></li>
</ol>
</li>
<li><a href="#cosa-sono-i-costruttori-in-java">Costruttori</a></li>
<li><a href="#cosa-sono-i-modificatori-di-accesso-in-java">Modificatori di accesso</a></li>
<li><a href="#cosa-sono-i-metodi-getter-e-setter-in-java">Getter e setter</a></li>
<li><a href="#cos-l-ereditariet-in-java">Ereditarietà</a></li>
<li><a href="#come-sovrascrivere-un-metodo-in-java">Sovrascrivere un metodo</a></li>
<li><a href="#conclusione">Conclusione</a></li>
</ol>
<!--kg-card-end: markdown--><h2 id="prerequisiti"><strong><strong><strong>Prerequisit</strong></strong>i</strong></h2><p>L'unico requisito per questo corso è avere familiarità con un qualsiasi altro linguaggio di programmazione come Python, JavaScript e via dicendo.</p><p>Anche se spiegherò concetti di programmazione fondamentali nel contesto di Java, non parlerò di cose come cos'è una variabile nell'ambito della programmazione in generale.</p><h2 id="come-scrivere-hello-world-in-java"><strong>Come scrivere Hello World in Java</strong></h2><p>Idealmente, il primo passo dovrebbe essere impostare Java sul tuo computer, ma non voglio annoiarti con il download e l'installazione di un mucchio di software proprio all'inizio. Per questo esempio, userai la piattaforma <a href="https://replit.com/">https://replit.com/</a>.</p><p>Prima di tutto, vai su <a href="https://replit.com/">https://replit.com/</a> e crea un nuovo account se non ne hai già uno. Puoi usare il tuo account Google/GitHub/Facebook esistente per accedere. Una volta fatto il login, ti troverai nella tua home. Da qui, usa il pulsante <strong>Create </strong>sotto <strong>My Repls</strong> per creare un nuovo repl.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/07/image-201.png" class="kg-image" alt="image-201" width="600" height="400" loading="lazy"></figure><p>Nella finestra <strong>Create a Repl</strong>, scegli <strong>Java </strong>com <strong>Template</strong>, imposta un titolo descrittivo (nel campo Title) come <strong>Hello World</strong> e premi il pulsante <strong>Create Repl</strong>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/07/image-202.png" class="kg-image" alt="image-202" width="600" height="400" loading="lazy"></figure><p>Ti verrà mostrato un editor di codice con un terminale integrato, come il seguente:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/07/image-203.png" class="kg-image" alt="image-203" width="600" height="400" loading="lazy"></figure><p>Sul lato sinistro c'è la lista dei file di questo progetto, al centro c'è l'editor di codice e sulla destra il terminale.</p><p>Il template contiene già del codice predefinito. Puoi eseguire il codice premendo il pulsante <strong>Run</strong>. Prosegui pure eseguendo il programma.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/07/image-205.png" class="kg-image" alt="image-205" width="600" height="400" loading="lazy"></figure><p>Se tutto funziona a dovere, dovresti vedere le parole "Hello world!" stampate sul lato destro. Congratulazioni, hai eseguito con successo il tuo primo programma in Java.</p><h3 id="cosa-succede-nel-codice"><strong>Cosa succede nel codice?</strong></h3><p>Il programma hello world è probabilmente il programma eseguibile Java più semplice che tu possa scrivere – e capirlo è cruciale.</p><pre><code class="language-java">class Main {
  public static void main(String[] args) {
    System.out.println("Hello world!");
  }
}</code></pre><p>Partiamo dalla prima riga:</p><pre><code class="language-java">class Main {
  //...
}</code></pre><p>Questa riga crea una classe <code>Main</code>. Una classe raggruppa insieme una porzione di codice correlato in una singola unità.</p><p>Questa è una classe <code>public</code>, che vuol dire che la classe è accessibile ovunque nel codebase. Un file sorgente Java (un file con l'estensione <code>.java</code>) può contenere al suo interno soltanto una classe <code>public</code> di livello più alto.</p><p>Questa classe pubblica con il livello più alto deve avere esattamente lo stesso nome del file con il codice sorgente. Ecco perché il file denominato <code>Main.java</code> contiene la classe <code>Main</code> in questo progetto.</p><p>Per capirne il motivo, clicca sui tre puntini nella lista dei file e clicca sull'opzione <strong><strong>Show hidden files</strong></strong>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/07/image-204.png" class="kg-image" alt="image-204" width="600" height="400" loading="lazy"></figure><p>Così facendo vedrai alcuni nuovi file all'interno del progetto, tra cui il file <code>Main.class</code>. È ciò che viene chiamato bytecode. Quando premi il pulsante Run, il compilatore Java compila il tuo codice dal file <code>Main.java</code> in questo bytecode.</p><p>Adesso, modifica il codice Hello World esistente come segue:</p><pre><code class="language-java">class Main {
  public static void main(String[] args) {
    System.out.println("Hello world!");
  }
}

class NotMain {
  public static void main(String[] args) {
    System.out.println("Not hello world!");
  }
}</code></pre><p>Come puoi vedere, una nuova classe chiamata <code>NotMain</code> è stata aggiunta. Prosegui e premi ancora il pulsante <strong>Run </strong>tenendo d'occhio il menu <strong>Files</strong>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/07/image-206.png" class="kg-image" alt="image-206" width="600" height="400" loading="lazy"></figure><p>È apparso un nuovo bytecode chiamato <code>NotMain.class</code>. Questo significa che per ogni classe presente nell'intero codebase, il compilatore creerà un bytecode separato.</p><p>Ciò crea confusione riguardo a quale classe sia il punto d'ingresso (entry-point) di questo programma. Per risolvere questo problema, Java usa la classe che corrispondente al nome del file con il codice sorgente come punto d'ingresso del programma.</p><p>Ma basta parlare della classe, adesso diamo un'occhiata alla funzione al suo interno: </p><pre><code class="language-java">class Main {
  public static void main(String[] args) {
    System.out.println("Hello world!");
  }
}</code></pre><p>La funzione <code>public static void main (String[] args)</code> ha un significato speciale in Java. Se hai esperienza con linguaggi come C, C++ o Go, dovresti già sapere che ogni programma in questi linguaggi possiede una funzione main. L'esecuzione del programma parte da questa funzione main.</p><p>In Java, devi scrivere questa funzione esattamente come <code>public static void main (String[] args)</code> altrimenti non funzionerà. Infatti, se la cambi anche di poco, Java inizierà a lamentarsi.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/07/image-207.png" class="kg-image" alt="image-207" width="600" height="400" loading="lazy"></figure><p>Il tipo del valore di ritorno è cambiato da <code>void</code> a <code>int</code> e la funzione adesso restituisce <code>0</code> alla fine. Come puoi vedere nella console, dice:</p><pre><code>Error: Main method must return a value of type void in class Main, please 
define the main method as:
   public static void main(String[] args)</code></pre><p>Ascolta il suggerimento e riporta il programma al suo stato precedente.</p><pre><code class="language-java">class Main {
  public static void main(String[] args) {
    System.out.println("Hello world!");
  }
}
</code></pre><p>Il metodo <code>main</code> è un metodo <code>public</code> e <code>static</code> vuol dire che puoi chiamarlo senza istanziare la sua classe.</p><p><code>void</code> significa che la funzione non restituisce nessun valore e <code>String[] args</code> vuol dire che la funzione prende un array di stringhe come argomento. Questo array contiene argomenti da riga di comando passati al programma durante l'esecuzione.</p><p><code>System.out.println</code> stampa delle stringhe sul terminale. Nell'esempio precedente, <code>"Hello world!"</code> è stata passata alla funzione, quindi otteniamo <code>Hello world!</code> stampato sul terminale.</p><p>In Java, ogni istruzione termina con un punto e virgola. <strong>A differenza di</strong> <strong><strong>JavaScript o Python, </strong>il punto e virgola <strong>in Java </strong>è obbligatorio</strong>. Saltarne uno farà fallire la compilazione.</p><p>Sostanzialmente è tutto per questo programma. Se non hai capito ogni aspetto dei questa sezione parola per parola, non preoccuparti. Diventerà tutto più chiaro andando avanti.</p><p>Per ora, ricorda che la classe <code>public</code> di livello più alto in un file sorgente Java deve corrispondere al nome del file e che la funzione main di ogni programma Java deve essere definita come <code>public static void main(String[] args)</code>.</p><h3 id="cos-la-jvm"><strong>Cos'è la JVM?</strong></h3><p>Nella sezione precedente, ho già usato un paio di volte la parola "bytecode". Ho anche detto che Java è "multi-piattaforma", che vuol dire che il codice scritto e compilato su una piattaforma può girare su qualsiasi piattaforma che ha Java installato.</p><p>Il tuo processore non comprende l'italiano o l'inglese. Infatti, l'unica cosa che comprende sono gli zero e gli uno, ovvero il linguaggio binario.</p><p>Quando scrivi e compili un programma in C++, il risultato è un file binario. Il processore lo comprende e, in base alla piattaforma designata del programma, questo file può essere diverso.</p><p>Ad esempio, prendiamo dei processori AMD64 e ARMv8-A. Questi processori hanno un set di istruzioni differenti. Quindi, per eseguire un programma su queste due diverse piattaforme, dobbiamo compilarlo separatamente.</p><p>Ma un programma Java può essere scritto una volta ed eseguito ovunque. Spero ti ricordi dei bytecode di cui abbiamo parlato nella sezione precedente. Quando compili del codice Java il risultato non è in binario ma in bytecode.</p><p>Il bytecode non è interamente binario, ma è comunque non leggibile da una persona, e nemmeno dal tuo processore.</p><p>Quindi invece di dare questo bytecode alla CPU, lo eseguiamo attraverso la Java Virtual Machine (o JVM in breve) che legge e interpreta il bytecode per la CPU. </p><p>Se vuoi comprendere l'architettura della JVM nel dettaglio, ti suggerisco <a href="https://www.freecodecamp.org/italian/news/tutorial-jvm-larchitettura-della-java-virtual-machine-spiegata-per-principianti/">questo articolo</a> di <a href="https://www.freecodecamp.org/news/author/theawesomenayak/">Siben Nayak</a> sull'argomento.</p><h3 id="cosa-sono-jre-e-jdk"><strong>Cosa sono JRE e JDK?</strong></h3><p>JRE sta per Java Runtime Environment e JDK sta per Java Development Kit.</p><p>Il JRE o Java Runtime Environment racchiude un'implementazione della JVM insieme a un set di librerie richieste per eseguire i programmi Java.</p><p>Il JDK, d'altro canto, contiene il JRE insieme a tutte le librerie necessarie per sviluppare programmi in Java.</p><p>Quindi, se vuoi eseguire programmi Java sul tuo computer, dovrai installare il JRE. Mentre se vuoi sviluppare dei programmi Java, dovrai installare il JDK, di cui esistono diverse implementazioni.</p><p>Tra di esse, <a href="https://www.oracle.com/java/technologies/downloads/">Java SE (Standard Edition) Development Kit</a> di Oracle, <a href="https://openjdk.org/">OpenJDK</a>, un'implementazione ufficiale di riferimento di Java SE (Standard Edition) Development Kit.</p><p>Come puoi immaginare dal suo nome, OpenJDK è open-source, quindi ne esistono svariate versioni. Se hai una macchina Linux e usi il tuo gestore di pacchetti di distro per installare JDK, è molto probabile che installerai una versione OpenJDK come <a href="https://adoptium.net/">Adoptium</a>, <a href="https://docs.microsoft.com/en-us/java/openjdk/"></a><a href="https://learn.microsoft.com/it-it/java/openjdk/">Microsoft Build di OpenJDK</a> e così via.</p><p>Spero che tu abbia capito che il JRE è un sovrainsieme della JVM e che il JDK è un sovrainsieme del JRE. Per ora, non preoccuparti delle diverse implementazioni o versioni, lo farai a tempo debito.</p><h2 id="come-configurare-java-sul-tuo-computer"><strong>Come configurare Java sul tuo computer</strong></h2><p>Prima di tutto, vai su <a href="https://www.oracle.com/java/technologies/downloads/">https://www.oracle.com/java/technologies/downloads/</a> e scarica l'ultima versione di <strong><strong>Java SE Development Kit</strong></strong> in base alla piattaforma su cui ti trovi:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/07/image-208.png" class="kg-image" alt="image-208" width="600" height="400" loading="lazy"></figure><p>Una volta terminato il download, avvia l'installazione e segui il processo di installazione premendo i pulsanti Avanti. Termina premendo il pulsante Chiudi nell'ultima pagina.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/07/image-235.png" class="kg-image" alt="image-235" width="600" height="400" loading="lazy"></figure><p>Il processo di installazione può variare su macOS e Linux ma dovresti essere in grado di venirne a capo.</p><p>Una volta che l'installazione è terminata, esegui il seguente comando sul tuo terminale:</p><pre><code>java --version

# java 18.0.2 2022-07-19
# Java(TM) SE Runtime Environment (build 18.0.2+9-61)
# Java HotSpot(TM) 64-Bit Server VM (build 18.0.2+9-61, mixed mode, sharing)</code></pre><p>Se funziona, hai installato con successo Java SE Development Kit sul tuo computer. Se invece vuoi usare OpenJDK, scarica pure <a href="https://docs.microsoft.com/en-us/java/openjdk/"></a><a href="https://learn.microsoft.com/it-it/java/openjdk/">Microsoft Build di OpenJDK</a> o <a href="https://adoptium.net/">Adoptium</a> e segui il processo di installazione.</p><p>Per i semplici programmi di esempio che scriveremo in questo articolo, non importa quale JDK utilizzi, ma per un utilizzo pratico, assicurati che la tua versione di JDK sia adatta al tipo di progetto su cui lavori.</p><h2 id="come-installare-un-ide-java-sul-tuo-computer"><strong>Come installare un IDE Java sul tuo computer</strong></h2><p>Quando si tratta di Java, <a href="https://www.jetbrains.com/idea/">IntelliJ IDEA</a> è senza dubbio il migliore ambiente di sviluppo integrato (IDE) in circolazione. Persino Google lo utilizza come base per <a href="https://developer.android.com/studio">Android Studio</a>.</p><p>L'ultima versione dell'IDE <a href="https://www.jetbrains.com/idea/buy/#personal">può costare fino a € 169.00 all'anno</a>. Ma se sei uno studente, puoi ottenere gratuitamente una <a href="https://www.jetbrains.com/community/education/#students">licenza per studenti</a> per tutti i prodotti JetBrains.</p><p>Esiste anche una edizione community open-source, completamente gratuita, che utilizzerò per tutto il manuale.</p><p>Vai sulla <a href="https://www.jetbrains.com/idea/download/#section=windows">pagina di download di IntelliJ IDEA</a> e scarica l'edizione community per la tua piattaforma.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/08/image-344.png" class="kg-image" alt="image-344" width="600" height="400" loading="lazy"></figure><p>Una volta finito il download, installa IntelliJ IDEA come qualsiasi altro software.</p><h2 id="come-creare-un-nuovo-progetto-su-intellij-idea"><strong>Come creare un nuovo progetto su IntelliJ IDEA</strong></h2><p>Usa la scorciatoia dal menu start per avviare IntelliJ IDEA. Ti apparirà la seguente finestra:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/08/image-346.png" class="kg-image" alt="image-346" width="600" height="400" loading="lazy"></figure><p>Usa il pulsante <strong><strong>New Project</strong></strong> e vedrai una finestra <strong><strong>New Project</strong></strong>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/08/image-347.png" class="kg-image" alt="image-347" width="600" height="400" loading="lazy"></figure><p>Dai un nome descrittivo al tuo progetto. Lascia le altre opzioni come sono e premi il pulsante <strong>Create</strong>.</p><p>La creazione del progetto non dovrebbe richiedere più di qualche secondo e, fatto questo, ti apparirà la finestra qui sotto:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/08/image-348.png" class="kg-image" alt="image-348" width="600" height="400" loading="lazy"></figure><p>A sinistra trovi la finestra degli strumenti del progetto. Tutti il codice sorgente sarà all'interno di questa cartella <code>src</code>.</p><p>Clicca con il tasto destro sulla cartella <code>src</code> e vai su <strong><strong>New &gt; Java Class</strong></strong>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/08/image-349.png" class="kg-image" alt="image-349" width="600" height="400" loading="lazy"></figure><p>Per il prossimo passaggio, dai un nome come <code>Main</code> alla classe e assicurati che il tipo sottolineato sia Class.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/08/image-350.png" class="kg-image" alt="image-350" width="600" height="400" loading="lazy"></figure><p>Una nuova classe sarà creata con poche righe di codice.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/08/image-351.png" class="kg-image" alt="image-351" width="600" height="400" loading="lazy"></figure><p>Aggiorna il codice come segue:</p><pre><code class="language-java">public class Main {
    public static void main (String[] args) {
        System.out.println("Hello World!");
    }
}
</code></pre><p>Per eseguire questo codice, usa il pulsante verde sul lato destro della barra superiore.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/08/image-352.png" class="kg-image" alt="image-352" width="600" height="400" loading="lazy"></figure><p>Il codice sarà eseguito e l'output verrà mostrato nel terminale integrato nella parte inferiore della finestra.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/08/image-353.png" class="kg-image" alt="image-353" width="600" height="400" loading="lazy"></figure><p>Congratulazioni, hai ricreato con successo in IntelliJ IDEA il programma <code>Hello World</code> precedentemente discusso.</p><h2 id="come-lavorare-con-le-variabili-in-java"><strong>Come lavorare con le variabili in Java</strong></h2><p>Per lavorare con diversi tipi di dati in Java, puoi creare variabili di vario tipo. Ad esempio, se vuoi memorizzare la tua età in una nuova variabile, puoi farlo in questo modo:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		// &lt;tipo&gt; &lt;nome&gt;
		int eta;

	}

}
</code></pre><p>Inizia a scrivere il tipo di dato o variabile. Visto che <code>eta</code> è un numero intero, il suo tipo sarà un intero, o <code>int</code>, seguito dal nome della variabile <code>eta</code> e da un punto e virgola.</p><p>Per ora, hai dichiarato la variabile ma non l'hai ancora inizializzata. In altre parole, la variabile non ha nessun valore. Puoi inizializzare la variabile come segue:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		// &lt;tipo&gt; &lt;nome&gt;
		int eta;
		
		// &lt;nome&gt; = &lt;valore&gt;
		eta = 27;
        
		// stampa sul terminale "Ho 27 anni."
		System.out.println("Ho " + eta + " anni.");

	}

}</code></pre><p>Per assegnare un valore, inizia a scrivere il nome della variabile che desideri inizializzare, seguito dal segno uguale (<code>=</code>, chiamato operatore di assegnazione) e dal valore che vuoi assegnare alla variabile. Non dimenticare il punto e virgola alla fine.</p><p>La chiamata della funzione <code>System.out.println();</code> stamperà la frase <code>Ho 27 anni.</code> sulla console. Nel caso te lo stessi chiedendo, usare il segno più è uno dei tanti modi per stampare delle variabili in modo dinamico in mezzo a una frase.</p><p>Una cosa che devi tenere a mente è che non puoi usare una variabile non inizializzata in Java. Quindi se trasformi la riga <code>eta = 27</code> in un commento, anteponendovi due barre oblique e provi a compilare il codice, il compilatore ti darà il seguente messaggio di errore:</p><pre><code>Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The local variable eta may not have been initialized

	at variables.Main.main(Main.java:13)</code></pre><p>La riga <code>The local variable eta may not have been initialized</code> indica che la variabile non è stata inizializzata.</p><p>Invece di dichiarare e inizializzare la variabile su righe diverse, puoi farlo in un colpo solo, in questo modo:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		// &lt;tipo&gt; &lt;nome&gt; = &lt;valore&gt;
		int eta = 27;
        
		// stampa sul terminale "Ho 27 anni."
		System.out.println("Ho " + eta + " anni.");

	}

}</code></pre><p>Il codice dovrebbe essere tornato alla normalità. Puoi anche cambiare il valore di una variabile quante volte desideri nel tuo codice.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int eta = 27;
        
		// aggiorna il valore a 28 invece di 27
		eta = 28;
        
		System.out.println("Ho " + eta + " anni.");

	}

}</code></pre><p>In questo codice, il valore di <code>eta</code> cambia da <code>27</code> a <code>28</code> perché lo stiamo sovrascrivendo prima di stamparlo.</p><p>Tieni a mente che mentre puoi assegnare un valore a una variabile quante volte desideri, non puoi dichiarare la stessa variabile due volte.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		// &lt;tipo&gt; &lt;nome&gt; = &lt;valore&gt;
		int eta = 27;
        
		int eta = 28;
        
		// stampa sul terminale
		System.out.println("Ho " + eta + " anni.");

	}

}</code></pre><p>Se provi a compilare questo codice, il compilatore ti restituirà il seguente errore:</p><pre><code>Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	Duplicate local variable eta

	at variables.Main.main(Main.java:9)
</code></pre><p>La riga <code>Duplicate local variable eta</code> indica che la variabile è già stata dichiarata.</p><p>Oltre alle variabili, su internet potresti trovare il termine "letterale". I letterali sono variabili con valori con codifica fissa.</p><p>Ad esempio, in questo caso, <code>eta = 27</code> non è calcolato dinamicamente. Il valore è scritto direttamente nel codice sorgente, quindi <code>eta</code> è un intero letterale.</p><h3 id="quali-sono-le-regole-per-dichiarare-le-variabili"><strong>Quali sono le regole per dichiarare le variabili?</strong></h3><p>Esistono alcune regole che riguardano la nomenclatura delle variabili in Java. Puoi utilizzare qualsiasi nome, a patto che non inizi con un numero e non contenga spazi.</p><p>Nonostante sia possibile iniziare il nome di una variabile con un trattino basso (_) o il simbolo del dollaro ($), non essere consapevole del loro utilizzo può rendere il codice difficile da leggere. I nomi delle variabili sono anche <em>case sensitive</em>, quindi <code>eta</code> e <code>ETA</code> sono due variabili diverse.</p><p>Un'altra cosa importante da ricordare è che non puoi usare nessuna delle parole chiave riservate in Java. Al momento, ne esistono circa 50. Puoi conoscere queste parole chiave grazie alla <a href="https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html">documentazione ufficiale</a>, ma non preoccuparti di memorizzarle.</p><p>Man mano che continui a fare pratica, quelle importanti si annideranno nel tuo cervello automaticamente. E se stai ancora facendo confusione con la dichiarazione di una variabile, il compilatore sarà lì a ricordarti che c'è qualcosa di sbagliato.</p><p>Oltre alle regole, ci sono alcune convenzioni che dovresti seguire:</p><ul><li>Il nome di una variabile dovrebbe iniziare con una lettera minuscola e non con un carattere speciale (come un trattino basso o il simbolo del dollaro).</li><li>Se il nome della variabile contiene più parole, usa il camel case: <code>primaVariabile</code>, <code>secondaVariabile</code></li><li>Non usare lettere singole come nome: <code>f</code>, <code>l</code></li></ul><p>Finché segui queste regole e convenzioni, sei a posto. Se vuoi imparare di più sulle convenzioni di nomenclatura in generale, dai un'occhiata a <a href="https://www.freecodecamp.org/italian/news/convenzioni-di-nomenclatura-nella-programmazione-camel-snake-kebab-e-pascal-case-spiegati/">questo mio articolo</a> sull'argomento.</p><h3 id="cosa-sono-le-variabili-final"><strong>Cosa sono le variabili <code>final</code>?</strong></h3><p>Una variabile <code>final</code> in Java può essere assegnata solo una volta. Quindi se inizializzi una variabile come <code>final</code>, non puoi riassegnarla.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		// final &lt;tipo&gt; &lt;nome&gt; = &lt;valore&gt;
		final int eta = 27;
		
		eta = 28;
        
		System.out.println("Ho " + eta + " anni.");

	}

}</code></pre><p>Dato che la variabile <code>eta</code> è stata dichiarata come <code>final</code>, otterrai il seguente messaggio di errore:</p><pre><code>Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The final local variable eta cannot be assigned. It must be blank and not using a compound assignment

	at variables.Main.main(Main.java:9)
</code></pre><p>Tuttavia, se lasci la variabile non inizializzata quando la dichiari, il codice funzionerà:</p><pre><code>public class Main {

	public static void main(String[] args) {
		// final &lt;tipo&gt; &lt;nome&gt;
		final int eta;
		
		eta = 28;
        
		// stampa sul terminale "Ho 28 anni."
		System.out.println("Ho " + eta + " anni.");

	}

}</code></pre><p>Quindi, dichiarare una variabile come <code>final</code> limiterà l'abilità di riassegnarle un valore. Se la lasci non inizializzata, poi sarai in grado di inizializzarla normalmente.</p><h2 id="quali-sono-i-tipi-di-dati-primitivi-in-java"><strong>Quali sono i tipi di dati primitivi in Java?</strong></h2><p>A un livello elevato, ci sono due tipi di dati in Java: "primitivi" e "non primitivi" o "riferimenti" (reference).</p><p>I tipi primitivi contengono valori. Ad esempio, <code>int</code> è un tipo primitivo e contiene un valore intero.</p><p>Un tipo riferimento, d'altro canto, contiene il riferimento a una posizione in memoria in cui viene conservato un oggetto dinamico.</p><p>Esistono otto tipi di dati primitivi in Java.</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Tipo</th>
<th>Descrizione</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>byte</code></td>
<td>8 bit, numero intero con segno compreso tra -128 e 127</td>
</tr>
<tr>
<td><code>short</code></td>
<td>16 bit, numero intero con segno compreso tra -32,768 e 32,767</td>
</tr>
<tr>
<td><code>int</code></td>
<td>32 bit, numero intero con segno compreso tra -2147483648 e 2147483647</td>
</tr>
<tr>
<td><code>long</code></td>
<td>64 bit, numero intero con segno compreso tra -9223372036854775808 e 9223372036854775807</td>
</tr>
<tr>
<td><code>float</code></td>
<td>32 bit, numero in virgola mobile con precisione singola compreso tra 1.4E-45 e 3.4028235E38</td>
</tr>
<tr>
<td><code>double</code></td>
<td>64 bit, numero in virgola mobile con precisione doppia compreso tra 4.9E-324 e 1.7976931348623157E308</td>
</tr>
<tr>
<td><code>boolean</code></td>
<td><code>true</code> o <code>false</code></td>
</tr>
<tr>
<td><code>char</code></td>
<td>16-bit, singolo carattere Unicode compreso tra <code>\u0000</code> (o 0) e <code>\uffff</code> (o 65,535 incluso)</td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><p>Sì, lo so che questa tabella spaventa ma non stressarti. Non devi memorizzarli.</p><p>Non hai bisogno di pensare a questi intervalli molto di frequente, e anche se lo fai, ci sono modi per visualizzarli nel tuo codice Java.</p><p>In ogni caso, se non sai cosa è un bit, ti consiglio <a href="https://www.freecodecamp.org/news/binary-definition/">questo breve articolo</a> riguardo al linguaggio binario.</p><p>Hai già imparato come dichiarare un intero nella sezione precedente. Puoi dichiarare <code>byte</code>, <code>short</code> o <code>long</code> allo stesso modo.</p><p>Anche dichiarare un <code>double</code> funziona allo stesso modo, eccetto per il fatto che puoi assegnare un numero con un punto decimale invece di un intero:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		double gpa = 4.8;
		
		System.out.println("Il mio GPA è " + gpa + ".");

	}
}</code></pre><p>Se assegni un <code>int</code> a un <code>double</code>, come <code>4</code> invece di <code>4.8</code>, l'output sarà <code>4.0</code> invece di <code>4</code>, perché un <code>double</code> ha sempre il punto decimale.</p><p>Dato che <code>double</code> e <code>float</code> sono simili, potresti pensare che sostituire la parola chiave <code>double</code> con <code>float</code> convertirà la variabile in un numero in virgola mobile – ma non è corretto. Dovrai aggiungere una <code>f</code> o <code>F</code> dopo il valore:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		float gpa = 4.8f;
		
		System.out.println("Il mio GPA è " + gpa + ".");

	}
}</code></pre><p>Ciò accade perché, di default, ogni numero con un punto decimale è trattato come un <code>double</code> in Java. Se non aggiungi la <code>f</code>, il compilatore penserà che stai cercando di assegnare un valore <code>double</code> a una variabile <code>float</code>.</p><p>I dati di tipo <code>boolean</code> possono essere i valori <code>true</code> o <code>false</code>.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		boolean fineSettimana = false;
		
		System.out.println(fineSettimana); // false

	}
}</code></pre><p>Come puoi immaginare, <code>false</code> può essere trattato come no e <code>true</code> può essere trattato come sì.</p><p>I booleani diventeranno molto più utili una volta che imparerai le istruzioni condizionali. Per ora, ricorda soltanto che valori possono contenere.</p><p>Il tipo <code>char</code> può contenere qualsiasi carattere Unicode in un certo intervallo.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		char segnoPercentuale = '%';
		
		System.out.println(segnoPercentuale); // %

	}
}</code></pre><p>In questo esempio, abbiamo salvato il segno della percentuale in una variabile <code>char</code> per poi stamparla sul terminale.</p><p>Puoi usare anche delle sequenze Unicode di escape per stampare determinati simboli.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		char simboloCopyright = '\u00A9';
		
		System.out.println(simboloCopyright); // ©

	}
}</code></pre><p>La sequenza di escape Unicode per il simbolo del copyright, ad esempio, è <code>\u00A9</code> e puoi trovare altre sequenze Unicode di escape in <a href="https://www.rapidtables.com/code/text/unicode-characters.html">questo sito</a>.</p><p>Tra questi 8 tipi di dati, quelli che userai più di frequente sono <code>int</code>, <code>double</code>, <code>boolean</code> e <code>char</code>.</p><h3 id="cos-una-conversione-di-tipo-o-casting"><strong>Cos'è una conversione di tipo o casting?</strong></h3><p>Una conversione di tipo in Java può essere "implicita" o "esplicita". Quando il compilatore converte un tipo di dato con un intervallo più ristretto in uno più ampio automaticamente, si parla di conversione di tipo implicita o di widening.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int numero1 = 8;
		double numero2 = numero1;
		
		System.out.println(numero2); // 8.0
	}

}
</code></pre><p>Visto che un <code>double</code> è più grande di un intero, il compilatore può facilmente eseguire la conversione. Invece, se provi a fare il contrario, otterrai questo errore dal compilatore:</p><pre><code>Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	Type mismatch: cannot convert from double to int

	at operators.Main.main(Main.java:7)
</code></pre><p>Quando esegui una conversione implicita, il flusso di conversione dovrebbe essere il seguente:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/08/widening-conversion.svg" class="kg-image" alt="widening-conversion" width="600" height="400" loading="lazy"></figure><p>Naturalmente, puoi passare da <code>short</code> a <code>double</code>, ad esempio, saltando gli altri nel mezzo.</p><p>Puoi anche passare da dati con intervallo più ampio a dati con intervallo più ristretto. In questo caso, parliamo di conversione di tipo esplicita o di narrowing.</p><pre><code class="language-java">package datatypes;

public class Main {

	public static void main(String[] args) {
		double numero1 = 8.5;
		int numero2 = (int) numero1;
		
		System.out.println(numero2); // 8
	}

}</code></pre><p>Precedentemente, abbiamo visto che se provi a convertire un tipo di dato più grande in uno più piccolo il compilatore si lamenta. Ma quando aggiungi l'operatore di cast <code>(int)</code> esplicitamente, fai vedere al compilatore chi è che comanda.</p><p>Facendo ciò, perdi una parte dei dati. Se cambi il numero <code>double</code> iniziale da <code>8.5</code> in <code>8</code>, perdi delle informazioni. Quindi ogni volta che fai una conversione esplicita, fai attenzione.</p><p>Puoi anche convertire un <code>char</code> in un <code>int</code> come segue:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		char carattere = 'F';
		int numero = carattere;
		
		System.out.println(numero); // 70
	}

}
</code></pre><p><code>70</code> è il codice ASCII per il carattere <code>F</code> – ecco il perché di questo output. Se vuoi saperne di più sui codici ASCII, il mio collega <a href="https://www.freecodecamp.org/news/author/kris/">Kris Koishigawa</a> ha scritto un <a href="https://www.freecodecamp.org/news/ascii-table-hex-to-ascii-value-character-code-chart-2/">eccellente articolo sull'argomento</a>.</p><p>Il flusso di conversione in questo caso sarà opposto a quello visto in precedenza.</p><figure class="kg-card kg-image-card kg-width-full"><img src="https://www.freecodecamp.org/news/content/images/2022/08/narrowing-conversion.svg" class="kg-image" alt="narrowing-conversion" width="600" height="400" loading="lazy"></figure><p>Ti suggerisco di sperimentare convertendo diversi valori da un tipo all'altro e vedere cosa accade. In questo modo, approfondirai la tua comprensione e acquisirai sicurezza.</p><h3 id="cosa-sono-le-classi-wrapper-in-java"><strong>Cosa sono le classi wrapper in Java?</strong></h3><p>Le classi wrapper (o involucro) possono contenere i tipi di dati primitivi e trasformarli in riferimenti. Le classi wrapper sono disponibili per tutti gli otto tipi di dati primitivi.</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Tipo Primitivo</th>
<th>Classe Wrapper</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>int</code></td>
<td><code>Integer</code></td>
</tr>
<tr>
<td><code>long</code></td>
<td><code>Long</code></td>
</tr>
<tr>
<td><code>short</code></td>
<td><code>Short</code></td>
</tr>
<tr>
<td><code>byte</code></td>
<td><code>Byte</code></td>
</tr>
<tr>
<td><code>boolean</code></td>
<td><code>Boolean</code></td>
</tr>
<tr>
<td><code>char</code></td>
<td><code>Character</code></td>
</tr>
<tr>
<td><code>float</code></td>
<td><code>Float</code></td>
</tr>
<tr>
<td><code>double</code></td>
<td><code>Double</code></td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><p>Puoi usare le classi wrapper come segue:</p><pre><code class="language-java">public class Main {
    public static void main (String[] args) {
        Integer eta = 27;
        Double gpa = 4.8;

        System.out.println(eta); // 27
        System.out.println(gpa); // 4.8
    }
}</code></pre><p>Tutto ciò che devi fare è sostituire il tipo di dato primitivo con la classe wrapper equivalente. Questi riferimenti hanno anche metodi per estrarre da essi il tipo primitivo.</p><p>Ad esempio, <code>eta.intValue()</code> restituirà l'età come un intero primitivo e &nbsp;<code>gpa.doubleValue()</code> restituirà il GPA come un primitivo double.</p><p>Esistono metodi del genere per tutti gli otto tipi di dati. Sebbene vedrai dati primitivi per la maggior parte del tempo, le classi wrapper torneranno utili in alcuni casi che discuteremo in una sezione successiva.</p><h2 id="come-usare-gli-operatori-in-java"><strong>Come usare gli operatori in Java</strong></h2><p>Nell'ambito della programmazione, gli operatori sono determinati simboli che comunicano al compilatore di svolgere specifiche operazioni, come operazioni aritmetiche, di confronto o logiche.</p><p>Anche se in Java esistono sei tipi di operatori, qui non parlerò degli operatori bitwise. Parlare degli operatori bitwise in una guida per principianti potrebbe essere scoraggiante.</p><h3 id="cosa-sono-gli-operatori-aritmetici"><strong>Cosa sono gli operatori aritmetici?</strong></h3><p>Gli operatori aritmetici sono quelli che puoi usare per svolgere operazioni aritmetiche. Ne esistono cinque:</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Operatore</th>
<th>Operazione</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>+</code></td>
<td>Addizione</td>
</tr>
<tr>
<td><code>-</code></td>
<td>Sottrazione</td>
</tr>
<tr>
<td><code>*</code></td>
<td>Moltiplicazione</td>
</tr>
<tr>
<td><code>/</code></td>
<td>Divisione</td>
</tr>
<tr>
<td><code>%</code></td>
<td>Modulo (resto)</td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><p>Le operazioni di addizione, sottrazione, moltiplicazione e divisione sono piuttosto intuitive. Dai un'occhiata all'esempio di codice qui sotto per capire:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int numero1 = 10;
		int numero2 = 5;
		
		System.out.println(numero1 + numero2); // 15
		System.out.println(numero1 - numero2); // 5
		System.out.println(numero1 * numero2); // 50
		System.out.println(numero1 / numero2); // 2
		System.out.println(numero1 % numero2); // 0

	}

}</code></pre><p>Gli output delle prime quattro operazioni non hanno bisogno di spiegazioni. Nell'ultima operazione, abbiamo svolto un'operazione di modulo usando il simbolo <code>%</code>. Il risultato è <code>0</code> perché dividendo 10 per 2, il resto è nullo.</p><p>Addizione e moltiplicazione sono piuttosto semplici. Per la sottrazione, se il primo operando è minore del secondo, il risultato sarà un numero negativo, come nella vita reale.</p><p>Il tipo di dato con cui stai lavorando fa la differenza nel risultato delle operazioni di divisione e modulo.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int numero1 = 8;
		int numero2 = 5;
		
		System.out.println(numero1 / numero2); // 1
	}

}</code></pre><p>Anche se il risultato di questa operazione dovrebbe essere 1.6, ciò non accade. In Java, se dividi un intero per un altro intero, il risultato sarà un intero. Ma se cambi entrambi o uno dei due in un float/double, tutto torna alla normalità.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		double numero1 = 8;
		double numero2 = 5;
		
		System.out.println(numero1 / numero2); // 1.6
	}

}
</code></pre><p>Questo principio si applica anche all'operatore modulo. Se uno o entrambi gli operandi sono float/double, il risultato sarà un float/double.</p><h3 id="cosa-sono-gli-operatori-di-assegnazione"><strong>Cosa sono gli operatori di assegnazione?</strong></h3><p>Abbiamo già usato l'operatore di assegnazione in una sezione precedente.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		// &lt;tipo&gt; &lt;nome&gt; = &lt;valore&gt;
		int eta = 27;
        
		// stampa il valore di eta sul terminale
		System.out.println(eta);

	}

}</code></pre><p>Quando usi il simbolo <code>=</code> per assegnare un valore a una variabile, funziona come un operatore di assegnazione. Ma questa non è l'unica forma di questo operatore.</p><p>Combinando il normale operatore di assegnazione con gli operatori aritmetici, puoi ottenere risultati differenti.</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Operatore</th>
<th>Operazione</th>
<th>Equivalente a</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>+=</code></td>
<td><code>a += b</code></td>
<td><code>a = a + b</code></td>
</tr>
<tr>
<td><code>-=</code></td>
<td><code>a -= b</code></td>
<td><code>a = a - b</code></td>
</tr>
<tr>
<td><code>*=</code></td>
<td><code>a *= b</code></td>
<td><code>a = a * b</code></td>
</tr>
<tr>
<td><code>/=</code></td>
<td><code>a /= b</code></td>
<td><code>a = a / b</code></td>
</tr>
<tr>
<td><code>%=</code></td>
<td><code>a %= b</code></td>
<td><code>a = a % b</code></td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><p>Il seguente esempio di codice dovrebbe rendere le cose più chiare:</p><pre><code class="language-java">package operators;

public class Main {

	public static void main(String[] args) {
		double numero1 = 10;
		double numero2 = 5;
		
		numero1 += numero2;
		
		System.out.println(numero1); // 15
	}

}
</code></pre><p>Gli altri operatori funzionano allo stesso modo. Svolgono l'operazione e poi ne assegnano il risultato all'operando di sinistra.</p><p>Potrei darti una dimostrazione degli altri ma credo che se li provi tu stesso li capirai meglio. Dopotutto, l'esercizio e la pratica sono i soli modi per consolidare le tue conoscenze.</p><h3 id="cosa-sono-gli-operatori-di-confronto"><strong>Cosa sono gli operatori di confronto?</strong></h3><p>Gli operatori di confronto sono utilizzati per verificare la relazione tra due operandi. Ad esempio, se un operando è uguale a un altro oppure no.</p><p>Gli operatori di confronto restituiscono <code>true</code> o <code>false</code> a seconda dell'operazione svolta.</p><p>In Java, esistono sei operatori di confronto.</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Operatore</th>
<th>Descrizione</th>
<th>Esempio</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>==</code></td>
<td>Uguale</td>
<td><code>5 == 8</code> restituisce <code>false</code></td>
</tr>
<tr>
<td><code>!=</code></td>
<td>Diverso</td>
<td><code>5 != 8</code> restituisce <code>true</code></td>
</tr>
<tr>
<td><code>&gt;</code></td>
<td>Maggiore</td>
<td><code>5 &gt; 8</code> restituisce <code>false</code></td>
</tr>
<tr>
<td><code>&lt;</code></td>
<td>Minore</td>
<td><code>5 &lt; 8</code> restituisce <code>true</code></td>
</tr>
<tr>
<td><code>&gt;=</code></td>
<td>Maggiore o uguale</td>
<td><code>5 &gt;= 8</code> restituisce <code>false</code></td>
</tr>
<tr>
<td><code>&lt;=</code></td>
<td>Minore o uguale</td>
<td><code>5 &lt;= 8</code> restituisce <code>true</code></td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><p>Il seguente esempio di codice mostra l'utilizzo di questi operatori:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		double numero1 = 10;
		double numero2 = 5;
		
		System.out.println(numero1 == numero2); // false
		System.out.println(numero1 != numero2); // true
		System.out.println(numero1 &gt; numero2); // true
		System.out.println(numero1 &lt; numero2); // false
		System.out.println(numero1 &gt;= numero2); // true
		System.out.println(numero1 &lt;= numero2); // false
	}

}
</code></pre><p>L'utilizzo pratico di questi operatori diventerà più chiaro una volta che imparerai a conoscere le istruzioni condizionali in una sezione successiva.</p><p>Puoi usare questi operatori anche con i caratteri.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		char letteraMinuscola = 'a';
		char letteraMaiuscola = 'A';
		
		System.out.println(letteraMinuscola &gt; letteraMaiuscola); // ???
	}

}
</code></pre><p>Quale credi che sarà l'output di questo codice? Ti invito a scoprirlo da solo. Ricordi il valore ASCII dei caratteri? Hanno un ruolo importante nell'output di questo programma.</p><h3 id="cosa-sono-gli-operatori-logici"><strong>Cosa sono gli operatori logici?</strong></h3><p>Immagina il caso in cui un programma che hai scritto può essere usato solo da persone che hanno più di 18 anni ma meno di 40. La logica dovrebbe essere la seguente:</p><pre><code>puoi eseguire il programma se -&gt;
	eta &gt;= 18 e eta &lt;= 40</code></pre><p>Oppure il caso in cui un utente deve essere uno studente della tua scuola o un membro della libreria per prendere libri in prestito. In questa situazione, la logica sarebbe:</p><pre><code>può prendere libri in prestito se -&gt;
	studenteDellaScuola o membroDellaLibreria</code></pre><p>Queste decisioni logiche possono essere prese usando operatori logici. Esistono tre operatori del genere in Java.</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Operatore</th>
<th>Esempio</th>
<th>Descrizione</th>
</tr>
</thead>
<tbody>
<tr>
<td>And logico (<code>&amp;&amp;</code>)</td>
<td><code>eta &gt;= 18 &amp;&amp; eta &lt;= 40</code></td>
<td>Il risultato è <code>true</code> se entrambe le condizioni sono <code>true</code></td>
</tr>
<tr>
<td>Or logico (<code>||</code>)</td>
<td><code>studenteDellaScuola || membroDellaLibreria</code></td>
<td>Il risultato è <code>true</code> se una o entrambe le condizioni sono <code>true</code></td>
</tr>
<tr>
<td>Not (<code>!</code>)</td>
<td><code>!membroDellaLibreria</code></td>
<td>Il risultato è <code>false</code> se la condizione è <code>true</code> e viceversa</td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><p>Vediamo del codice con questi operatori, partendo dall'operatore logico and (<code>&amp;&amp;</code>):</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int eta = 20;
		
		System.out.println(eta &gt;= 18 &amp;&amp; eta &lt;= 40); // true
	}

}
</code></pre><p>In questo caso, ci sono due condizioni ai lati dell'operatore <code>&amp;&amp;</code>. Se e soltanto se entrambe le condizioni sono valutate come <code>true</code>, l'operazione and risulta essere <code>true</code>.</p><p>Se la prima condizione è <code>false</code>, il computer non valuterà l'altra condizione e restituirà <code>false</code>, perché se la prima è <code>false</code>, non c'è modo che l'intera operazione sia <code>true</code>.</p><p>L'operatore logico or (<code>||</code>) funziona in modo simile, ma in questo caso, se una delle due condizioni è vera, lo sarà anche il risultato dell'operazione:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		boolean studenteDellaScuola = true;
		boolean membroDellaLibreria = false;
		
		System.out.println(studenteDellaScuola || membroDellaLibreria); // true
	}

}
</code></pre><p>Se la prima condizione di un'operazione logica or è <code>true</code>, il computer non valuterà l'altra condizione è restituirà <code>true</code>, perché se la prima condizione viene valutata come <code>true</code> il risultato dell'operazione sarà <code>true</code> indipendentemente dall'altra condizione.</p><p>Infine, l'operatore not (<code>!</code>) valuta l'opposto della condizione. Dai un'occhiata all'esempio di codice qui sotto:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		boolean membroDellaLibreria = true;
		
		System.out.println(membroDellaLibreria); // true
		System.out.println(!membroDellaLibreria); // false
	}

}
</code></pre><p>Come puoi vedere, l'operatore not restituisce l'opposto di un dato valore booleano. L'operatore <code>!</code> è un operatore unario, che vuol dire che opera su un singolo operando.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		boolean membroDellaLibreria = true;
		boolean studenteDellaScuola = false;
		
		System.out.println(!studenteDellaScuola || membroDellaLibreria); // true
	}

}
</code></pre><p>In questo esempio, l'operatore not trasforma <code>studenteDellaScuola</code> in <code>true</code>, e l'operazione viene valutata <code>true</code>. Ma se modifichi il codice in questo modo:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		boolean membroDellaLibreria = true;
		boolean studenteDellaScuola = false;
		
		System.out.println(!(studenteDellaScuola || membroDellaLibreria)); // false
	}

}
</code></pre><p>L'operazione logica or avverrà prima e sarà <code>true</code>. L'operatore not ne trasformerà il risultato in <code>false</code>.</p><p>Anche se abbiamo usato due operandi per ogni operatore, puoi usarne quanti ne desideri. Puoi anche usare diversi operatori insieme.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		boolean studenteDellaScuola = true;
		boolean membroDellaLibreria = false;
		int eta = 10;
		
		System.out.println(studenteDellaScuola || membroDellaLibreria &amp;&amp; eta &gt; 18); // ???
	}

}
</code></pre><p>Quale pensi che sarà l'output di questo codice? Ti suggerisco di scoprirlo da solo. :)</p><h3 id="cosa-sono-gli-operatori-unari"><strong>Cosa sono gli operatori unari?</strong></h3><p>Esistono alcuni operatori che sono usati con un operando alla volta e vengono chiamati operatori unari. Nonostante ne esistano cinque, parlerò soltanto di due di loro.</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Operatore</th>
<th>Descrizione</th>
</tr>
</thead>
<tbody>
<tr>
<td>Incremento (<code>++</code>)</td>
<td>Incrementa un dato valore di 1</td>
</tr>
<tr>
<td>Decremento (<code>--</code>)</td>
<td>Decrementa un dato valore di 1</td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><p>Il seguente codice ne mostra bene il funzionamento:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int punteggio = 95;
		int turni = 11;
		
		punteggio++;
		turni--;
		
		System.out.println(punteggio); // 96
		System.out.println(turni); // 10
	}

}
</code></pre><p>Puoi anche usare questi operatori come prefissi:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int punteggio = 95;
		int turni = 11;
		
		++punteggio;
		--turni;
		
		System.out.println(punteggio); // 96
		System.out.println(turni); // 10
	}

}
</code></pre><p>Per ora, tutto semplice. Ma ci sono alcune leggere differenze tra la sintassi con suffisso e prefisso che devi conoscere. Guarda il codice qui sotto:</p><pre><code class="language-java">package operators;

public class Main {

	public static void main(String[] args) {
		int punteggio = 95;
		
		
		System.out.println(++punteggio); // 96
		System.out.println(punteggio); // 96
	}

}
</code></pre><p>Questo è il risultato atteso. L'operatore decremento usato come prefisso funziona allo stesso modo. Ma guarda cosa accade se passiamo alla sintassi con suffisso:</p><pre><code class="language-java">package operators;

public class Main {

	public static void main(String[] args) {
		int punteggio = 95;
		
		
		System.out.println(punteggio++); // 95
		System.out.println(punteggio); // 96
	}

}
</code></pre><p>Disorientante, vero? Quale credi che sia il valore reale della variabile adesso? È 96, vediamo perché.</p><p>Quando usiamo la sintassi con il suffisso all'interno della funzione print, la funzione incontra prima la variabile e poi la incrementa. Ed ecco perché nella seconda riga stampa il nuovo valore aggiornato.</p><p>Nel caso della sintassi con il prefisso, la funzione incontra l'operatore di incremento e svolge l'operazione. Poi prosegue stampando il valore aggiornato.</p><p>Stai attento perché questa piccola differenza può prenderti alla sprovvista. Oppure prova a evitare di incrementare o decrementare all'interno di chiamate di funzione. </p><h2 id="come-usare-le-stringhe-in-java"><strong>Come usare le stringhe in Java</strong></h2><p>In Java, il tipo <code>String</code> è uno dei rifermenti usati più di frequente. È un insieme di caratteri che puoi usare per formare righe di testo in un programma.</p><p>Esistono due modi per creare nuove stringhe in Java. Il primo è quello letterale:</p><pre><code class="language-java">public class Main {
	public static void main(String[] args) {
		String nome = "Farhan";
        
		System.out.println("Il mio nome è " + nome + ".");
	}

}</code></pre><p>Come puoi vedere, dichiarare e usare una variabile di tipo <code>String</code> in questo modo non è molto diverso da dichiarare tipi primitivi in Java.</p><p>Il secondo modo per creare una variabile di tipo <code>String</code> è usare l'operatore <code>new</code>.</p><pre><code class="language-java">public class Main {
	public static void main(String[] args) {
		// &lt;tipo&gt; &lt;nome&gt; = new &lt;tipo&gt;(&lt;valore&gt;)
		String nome = new String("Farhan");
        
		System.out.println("Il mio nome è " + nome + ".");
	}

}</code></pre><p>Questo programma funziona come il precedente ma con una leggera differenza.</p><p>La JVM mantiene una porzione della memoria del computer per memorizzare le stringhe. Questa porzione è detta string pool (o pool di stringhe).</p><p>Ogni volta che crei una nuova <code>String</code> nel modo letterale, il JVM controlla prima se la stringa esiste già nel pool. Se esiste, il JVM la riusa, altrimenti la crea.</p><p>D'altro canto, quando utilizzi l'operatore <code>new</code>, il JVM crea sempre un nuovo oggetto <code>String</code>. Il seguente programma dimostra chiaramente questo concetto:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		String stringaLetterale1 = "abc";
		String stringaLetterale2 = "abc";
		
		String oggettoStringa1 = new String("abc");
		String oggettoStringa2 = new String("abc");
		
		System.out.println(stringaLetterale1 == stringaLetterale2);
		System.out.println(oggettoStringa1 == oggettoStringa2);

	}

}
</code></pre><p>Come potresti già sapere, l'operatore <code>==</code> è usato per verificare l'uguaglianza. L'output del programma sarà:</p><pre><code>true
false</code></pre><p>Dato che <code>abc</code> era già nello string pool, la variabile <code>stringaLetterale2</code> la riutilizza. Nel caso di oggetti stringa invece, si tratta di due entità diverse.</p><h3 id="come-formattare-una-stringa"><strong>Come formattare una stringa</strong></h3><p>Abbiamo già visto l'utilizzo dell'operatore <code>+</code> per concatenare stringhe o formattarle in un modo specifico.</p><p>Questo approccio funziona finché non hai tante aggiunte a una stringa. È facile fare confusione con la posizione delle virgolette.</p><p>Un modo migliore di formattare una stringa è il metodo <code>String.format()</code>.</p><pre><code class="language-java">public class Main {
	public static void main(String[] args) {
		String nome = "Farhan";
		int eta = 27;
		
		String stringaFormattata = String.format("Il mio nome è %s e ho %d anni.", nome, eta);
        
		System.out.println(stringaFormattata);
	}

}</code></pre><p>Il metodo prende una stringa con degli specificatori di formato come primo argomento e gli argomenti per sostituire gli specificatori come argomenti successivi.</p><p>Nel codice qui sopra, i caratteri <code>%s</code> e <code>%d</code> sono specificatori di formato. Sono responsabili di comunicare al compilatore che quella parte della stringa deve essere sostituita con qualcosa.</p><p>Poi il compilatore sostituirà <code>%s</code> con <code>nome</code> e <code>%d</code> con <code>eta</code>. L'ordine degli specificatori deve corrispondere all'ordine degli argomenti e gli argomenti devono corrispondere al tipo indicato dallo specificatore.</p><p>I caratteri <code>%s</code> e <code>%d</code> non sono a caso. Sono specifici per stringhe e per interi decimali (in base dieci). Ecco una tabella degli specificatori usati comunemente:</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Specificatore</th>
<th>Tipo di dato</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>%b</code>, <code>%B</code></td>
<td>Booleano</td>
</tr>
<tr>
<td><code>%s</code>, <code>%S</code></td>
<td>Stringa</td>
</tr>
<tr>
<td><code>%c</code>, <code>%C</code></td>
<td>Carattere Unicode</td>
</tr>
<tr>
<td><code>%d</code></td>
<td>Intero in base dieci</td>
</tr>
<tr>
<td><code>%f</code></td>
<td>Numero in virgola mobile</td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><p>Ci sono anche <code>%o</code> per gli interi in base otto, <code>%x</code> o <code>%X</code> per i numeri esadecimali e <code>%e</code> o <code>%E</code> per le notazioni scientifiche, ma dato che non ne parlerò in questo manuale non li ho inseriti.</p><p>Proprio come gli specificatori <code>%s</code> e <code>%d</code> che hai visto, puoi usare gli altri specificatori per il tipo di dato corrispondente. E, nel caso te lo stessi chiedendo, lo specificatore <code>%f</code> funziona sia per i float che per i double.</p><h3 id="come-ottenere-la-lunghezza-di-una-stringa-e-verificare-se-una-stringa-vuota"><strong>Come ottenere la lunghezza di una stringa e verificare se una stringa è vuota</strong></h3><p>Controllare la lunghezza di una stringa o verificare se una stringa è vuota prima di svolgere delle operazioni è piuttosto comune.</p><p>Ogni oggetto stringa ha un metodo <code>length()</code> che ne restituisce la lunghezza. È come la proprietà <code>length</code> per gli array.</p><pre><code class="language-java">public class Main {
	public static void main(String[] args) {
		String nome = "Farhan";
        
		System.out.println(String.format("La lunghezza di questa stringa è: %d.", nome.length())); // 6
	}

}</code></pre><p>Il metodo restituisce la lunghezza come un intero, che puoi usare insieme allo specificatore di formato per gli interi.</p><p>Per verificare se una stringa è vuota o meno, puoi usare il metodo <code>isEmpty()</code>. Proprio come il metodo <code>length()</code>, può essere usato per ogni oggetto stringa.</p><pre><code class="language-java">public class Main {
	public static void main(String[] args) {
		String nome = "Farhan";
		
		if (nome.isEmpty()) {
			System.out.println("Non c'è nessun nome qui");
		} else {
			System.out.println(String.format("Okay, ci penso io a %s.", nome));
		}
	}

}</code></pre><p>Il metodo restituisce un valore booleano che puoi usare direttamente in una istruzione if. Il programma controlla se il nome è vuoto oppure no e stampa risposte diverse nei due casi.</p><h3 id="come-dividere-e-unire-delle-stringhe"><strong>Come dividere e unire delle stringhe</strong></h3><p>Il metodo <code>split()</code> può essere usato per dividere una stringa sulla base di un'espressione regolare.</p><pre><code class="language-java">import java.util.Arrays;

public class Main {
	public static void main(String[] args) {
		String nome = "Farhan Hasin Chowdhury";

		System.out.println(Arrays.toString(nome.split(" ")));
	}

}</code></pre><p>Il metodo restituisce un array di stringhe. Ogni stringa nell'array è una sottostringa della stringa originale. Qui, ad esempio, abbiamo diviso la stringa <code>Farhan Hasin Chowdhury</code> in corrispondenza di ogni spazio, quindi l'output sarà <code>[Farhan, Hasin, Chowdhury]</code>.</p><p>Come promemoria: un array è un insieme di più dati dello stesso tipo.</p><p>Dato che il metodo prende un'espressione regolare come argomento, possiamo sfruttarle per svolgere operazioni di suddivisione più complicate.</p><p>Puoi anche riunire insieme l'array per riformare la stringa, in questo modo:</p><pre><code class="language-java">public class Main {
	public static void main(String[] args) {
		String nome = "Farhan Hasin Chowdhury";
		
		String sottostringhe[] = nome.split(" ");
		
		String nomeUnito = String.join(" ", sottostringhe);

		System.out.println(nomeUnito); // Farhan Hasin Chowdhury
	}

}</code></pre><p>Il metodo <code>join()</code> può anche aiutarti a unire più stringhe insieme fuori da un array.</p><pre><code class="language-java">public class Main {
	public static void main(String[] args) {
		System.out.println(String.join(" ", "Farhan", "Hasin", "Chowdhury")); // Farhan Hasin Chowdhury
	}

}</code></pre><h3 id="come-convertire-una-stringa-in-maiuscolo-o-minuscolo"><strong>Come convertire una stringa in maiuscolo o minuscolo</strong></h3><p>Convertire una stringa in maiuscolo o minuscolo è un'operazione molto diretta in Java, che puoi svolgere rispettivamente con i metodi <code>toUpperCase()</code> e <code>toLowerCase()</code>:</p><pre><code class="language-java">public class Main {
	public static void main(String[] args) {
		String nome = "Farhan Hasin Chowdhury";

		System.out.println(name.toUpperCase()); // FARHAN HASIN CHOWDHURY
		
		System.out.println(name.toLowerCase()); // farhan hasin chowdhury
	}

}</code></pre><h3 id="come-confrontare-due-stringhe"><strong>Come confrontare due stringhe</strong></h3><p>Dato che le stringhe sono di tipo riferimento, non puoi confrontarle con l'operatore <code>==</code>.</p><p>Il metodo <code>equals()</code> controlla se due stringhe sono uguali o meno e il metodo <code>equalsIgnoreCase()</code> fa la stessa cosa ignorando le differenze nelle maiuscole/minuscole.</p><pre><code class="language-java">public class Main {
	public static void main(String[] args) {
		String nome = "Farhan Hasin Chowdhury";
		String nomeMaiuscolo = nome.toUpperCase();

		System.out.println(nome.equals(nomeMaiuscolo)); // false
		
		System.out.println(nome.equalsIgnoreCase(nomeMaiuscolo)); // true
	}

}</code></pre><h3 id="come-sostituire-caratteri-o-sottostringhe-in-una-stringa"><strong>Come sostituire caratteri o sottostringhe in una stringa</strong></h3><p>Il metodo <code>replace()</code> può essere usato per sostituire caratteri o intere sottostringhe di una data stringa.</p><pre><code class="language-java">package strings;

public class Main {
	public static void main(String[] args) {
		String loremIpsumStd = "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.";

		System.out.println(String.format("Standard lorem ipsum text: %s", loremIpsumStd));
		
		String loremIpsumHalfTranslated = loremIpsumStd.replace("Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium", "But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system");
		
		System.out.println(String.format("Translated lorem ipsum text: %s", loremIpsumHalfTranslated));
	}

}</code></pre><p>Qui, la stringa <code>loremIpsumStd</code> contiene una porzione del testo lorem ipsum originale. In seguito, la prima riga della stringa viene sostituita e la nuova stringa viene salvata nella variabile <code>loremIpsumHalfTranslated</code>.</p><h3 id="come-verificare-se-una-stringa-contiene-una-sottostringa"><strong>Come verificare se una stringa contiene una sottostringa</strong></h3><p>Il metodo <code>contains()</code> può verificare se una data stringa contiene una certa sottostringa oppure no.</p><pre><code class="language-java">public class Main {
	public static void main(String[] args) {
		String testo = "Le rose sono rosse, le viole sono blu";

		if (testo.contains("blu")) {
			System.out.println("Il testo contiene la parola blu.");
		} else {
			System.out.println("Il testo non contiene la parola blu.");
		}
	}

}</code></pre><p>Il metodo restituisce un valore booleano, quindi puoi utilizzarlo in una qualsiasi istruzione condizionale.</p><p>Questi erano alcuni dei più comuni metodi per stringhe. Se ne vuoi conoscere altri, consulta la <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/String.html">documentazione ufficiale</a>.</p><h2 id="quali-sono-i-diversi-modi-di-inserire-input-e-ottenere-output-di-dati"><strong>Quali sono i diversi modi di inserire input e ottenere output di dati?</strong></h2><p>Finora abbiamo imparato il metodo <code>System.out.println()</code> per stampare informazioni sul terminale. Abbiamo anche usato il metodo <code>String.format()</code> in una sezione precedente.</p><p>In questa sezione, imparerai a conoscere alcuni metodi parenti di <code>System.out.println()</code> e anche come prendere un input da un utente.</p><p>Prendere un input da un utente è estremamente semplice in linguaggi come Python. Tuttavia, in Java richiede qualche riga di codice in più.</p><pre><code class="language-java">import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		System.out.print("Come ti chiami? ");
		String nome = scanner.nextLine();
		
		System.out.printf("Ciao %s. Quanti anni hai? ", nome);
		int eta = scanner.nextInt();
		
		System.out.printf("Grande! %d anni sono un'ottima età per iniziare a programmare.", eta);
		
		scanner.close();

	}

}
</code></pre><p>La classe <code>java.util.Scanner</code> è necessaria per ricevere input utente. Puoi importarla nel tuo programma usando la parola chiave <code>import</code>.</p><p>Poi, dovrai creare una nuova istanza della classe <code>Scanner</code> usando la parola chiave <code>new</code>. Quando crei una nuova istanza, dovrai esplicitare il flusso di input desiderato.</p><p>Potresti voler prendere un input da un utente o da un file. In ogni caso, devi comunicarlo al compilatore. <code>System.in</code> è il flusso standard di input e output.</p><p>L'oggetto scanner ha metodi come <code>nextLine()</code> per prendere degli input stringa, <code>nextInt()</code> per prendere input interi, <code>nextDouble()</code> per input double e così via.</p><p>Nel codice precedente, il metodo <code>scanner.nextLine()</code> chiederà una stringa all'utente e restituirà l'input inserito con un carattere nuova riga dopo di esso.</p><p>Poi, il metodo <code>scanner.nextInt()</code> chiederà un intero e restituirà l'input dato dall'utente.</p><p>Potrebbe essere la prima volta che vedi il metodo <code>System.out.printf()</code>. Oltre al metodo <code>System.out.println()</code>, esiste anche il metodo <code>System.out.print()</code> che stampa una data stringa senza aggiungere un carattere nuova a riga al suo termine.</p><p><code>System.out.printf()</code> è una sorta di combinazione dei metodi <code>System.out.print()</code> e <code>String.format()</code>. Puoi usare gli specificatori di formato discussi precedente anche in questo metodo.</p><p>Una volta che l'input è stato accettato, è necessario chiudere l'oggetto scanner. Puoi farlo semplicemente chiamando il metodo <code>scanner.close()</code>.</p><p>Semplice, vero? Complichiamo un po' le cose.</p><pre><code class="language-java">import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("Come ti chiami? ");
        String nome = scanner.nextLine();

        System.out.printf("Ciao %s. Quanti anni hai? ", nome);
        int eta = scanner.nextInt();

        System.out.printf("Grande! %d anni sono un'ottima età per iniziare a programmare. \nChe linguaggio preferisci? ", eta);
        String linguaggio = scanner.nextLine();

        System.out.printf("Ah! %s è un linguaggio di programmazione molto valido.", linguaggio);

        scanner.close();

    }

}
</code></pre><p>Ho aggiunto un'istruzione <code>scanner.nextLine()</code> dopo la chiamata del metodo <code>scanner.nextInt()</code>. Funzionerà?</p><p>La risposta è no. Il programma salterà semplicemente l'ultimo prompt di input e stamperà l'ultima riga. Questo comportamento non è esclusivo di <code>scanner.nextInt()</code>. Se usi <code>scanner.nextLine()</code> dopo gli altri metodi <code>nextQualcosa()</code>, dovrai fare i conti con questo problema.</p><p>In breve, questo accade perché premi Invio per il metodo <code>scanner.nextInt()</code>, che prende l'intero e lascia il carattere nuova riga nel buffer dell'input.</p><p>Quindi, quando viene invocato <code>scanner.nextLine()</code>, consuma quel carattere nuova riga alla fine dell'input. La soluzione più semplice a questo problema è scrivere una chiamata aggiuntiva di <code>scanner.nextLine()</code> dopo le altre chiamate di un metodo scanner.</p><pre><code class="language-java">import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("Come ti chiami? ");
        String nome = scanner.nextLine();

        System.out.printf("Ciao %s. Quanti anni hai? ", nome);
        int eta = scanner.nextInt();

        // consuma il carattere nuova riga
        scanner.nextLine();

        System.out.printf("Grande! %d anni sono un'ottima età per iniziare a programmare. \nChe linguaggio preferisci? ", eta);
        String linguaggio = scanner.nextLine();

        System.out.printf("Ah! %s è un linguaggio di programmazione molto valido.", linguaggio);

        scanner.close();

    }

}
</code></pre><p>Esiste un altro modo per risolvere questo problema, ma non ne parlerò qui. Se sei interessato, dai un'occhiata a <a href="https://www.freecodecamp.org/italian/news/chiamata-saltata-del-metodo-scanner-nextline-in-java-errore-risolto/">questo mio articolo sull'argomento</a>.</p><h2 id="come-usare-le-istruzioni-condizionali-in-java"><strong>Come usare le istruzioni condizionali in Java</strong></h2><p>Puoi usare le istruzioni condizionali per prendere delle decisioni sulla base di condizioni specifiche.</p><p>Per questo, utilizziamo l'istruzione <code>if</code> come mostrato qui sotto:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int eta = 20;
		
		// if (condizione) {...}
		if (eta &gt;= 18 &amp;&amp; eta &lt;= 40) {
			System.out.println("Puoi usare il programma");
		}
		
	}

}
</code></pre><p>L'istruzione inizia con un <code>if</code>, seguito dalla condizione all'interno di parentesi. Se la condizione viene valutata come <code>true</code>, il codice all'interno delle parentesi graffe sarà eseguito.</p><p>Il codice racchiuso all'interno di parentesi graffe è detto blocco di codice.</p><p>Se cambi il valore di <code>eta</code> in <code>50</code>, l'istruzione print non sarà eseguita e non ci sarà alcun output sulla console. Per questo tipo di situazioni in cui la condizione viene valutata come <code>false</code>, puoi aggiungere un blocco <code>else</code>:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int eta = 20;
		
		if (eta &gt;= 18 &amp;&amp; age &lt;= 40) {
			System.out.println("Puoi usare il programma");
		} else {
			System.out.println("Non puoi usare il programma");
		}
		
	}

}
</code></pre><p>Ora, se la condizione viene valutata come <code>false</code>, sarà eseguito il codice nel blocco <code>else</code> e vedrai <code>Non puoi usare il programma</code> stampato sul terminale.</p><p>Puoi anche avere condizioni multiple all'interno di una scaletta <code>if</code>-<code>else if</code>-<code>else</code>:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int eta = 50;
		boolean studenteDellaScuola = true;
		boolean membroDellaLibreria = false;
		
		// if (condizione) {...}
		if (eta &gt;= 18 &amp;&amp; eta &lt;= 40) {
			System.out.println("Puoi usare il programma");
		} else if (studenteDellaScuola || membroDellaLibreria) {
			System.out.println("Puoi usare il programma per un tempo limitato");
		} else {
			System.out.println("Non puoi usare il programma");
		}
		
	}

}
</code></pre><p>Se la prima condizione viene valutata come <code>false</code>, viene testata la seconda condizione. Se la seconda condizione viene valutata come <code>true</code>, allora sarà eseguito il codice nelle parentesi graffe corrispondenti. Se le condizioni relative alle istruzioni <code>if</code> ed <code>else if</code> sono entrambe <code>false</code>, allora sarà eseguito il blocco <code>else</code>.</p><p>Puoi anche annidare delle istruzioni <code>if</code> all'interno di altre istruzioni <code>if</code> come segue:</p><pre><code class="language-java">package operators;

public class Main {

	public static void main(String[] args) {
		int eta = 20;
		
		if (eta &gt;= 18 &amp;&amp; eta &lt;= 40) {
			boolean studenteDellaScuola = true;
			boolean membroDellaLibreria = false;
			
			if (studenteDellaScuola || membroDellaLibreria) {
				System.out.println("Puoi usare il programma");
			}
		} else {
			System.out.println("Non puoi usare il programma");
		}
		
	}

}
</code></pre><p>In questo caso, l'istruzione <code>if</code> interna sarà testata solo se la prima istruzione <code>if</code> sarà valutata come <code>true</code>.</p><h2 id="cos-un-istruzione-switch-case"><strong>Cos'è un'istruzione switch-case?</strong></h2><p>Oltre ai blocchi <code>if</code>-<code>else</code>, esistono altri casi in cui è possibile definire condizioni multiple in una struttura che funge da interruttore.</p><pre><code class="language-java">import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("Qual è il primo operando? ");
        int a =scanner.nextInt();

        // consuma il carattere nuova riga
        scanner.nextLine();

        System.out.print("Qual è il secondo operando? ");
        int b = scanner.nextInt();

        // consuma il carattere nuova riga
        scanner.nextLine();

        System.out.print("Quale operazione vuoi svolgere? ");
        String operazione = scanner.nextLine();

        switch (operazione) {
            case "addizione":
                System.out.printf("%d + %d = %d", a, b, a+b);
                break;
            case "sottrazione":
                System.out.printf("%d - %d = %d", a, b, a-b);
                break;
            case "moltiplicazione":
                System.out.printf("%d * %d = %d", a, b, a*b);
                break;
            case "divisione":
                if (b == 0) {
                    System.out.print("Non puoi dividere per zero!");
                } else {
                    System.out.printf("%d / %d = %d", a, b, a / b);
                }
                break;
            default:
                System.out.printf("Operazione invalida!");
        }

        scanner.close();

    }

}
</code></pre><p>Questo è un programma per fare calcoli estremamente semplice. Il programma richiede due numeri all'utente e poi chiede che operazione eseguire.</p><p>Ogni istruzione switch-case ha uno <code>switch</code> e <code>case</code> multipli. Quando dici <code>"addizione"</code>, il programma verifica se il valore dello switch o della variabile <code>operazione</code> è o meno <code>addizione</code>.</p><p>Se corrisponde, il corpo del <code>case</code> sarà eseguito. Se nessuno dei casi corrisponde, viene eseguito il <code>default</code>.</p><p>Per quanto riguarda l'istruzione <code>break</code>, fa esattamente quello che sembra: ferma il programma dall'eseguire i casi successivi.</p><p>Se rimuovi le istruzioni <code>break</code>, tutti i casi vengono eseguiti uno dopo l'altro fino al caso <code>default</code>.</p><h2 id="cos-la-visibilit-di-una-variabile-in-java"><strong>Cos'è la visibilità di una variabile in Java?</strong></h2><p>La visibilità rappresenta il tempo di vita e l'accessibilità di una variabile. A seconda di dove dichiari una variabile potresti essere o non essere in grado di accedervi da altre posizioni.</p><p>Prendi come esempio il codice qui sotto:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int eta = 20;
		
		if (eta &gt;= 18 &amp;&amp; eta &lt;= 40) {
			// la variabile eta è accessibile qui
			// i booleani non sono accessibili qui

			boolean studenteDellaScuola = true;
			boolean membroDellaLibreria = false;
			
			if (studenteDellaScuola || membroDellaLibreria) {
				// i booleani sono accessibili qui
				// la variabile eta è accessibile qui

				System.out.println("Puoi usare il programma");
			}
		} else {
			// la variabile eta è accessibile qui
			// i booleani non sono accessibili qui
            
			System.out.println("Non puoi usare il programma");
		}
		
	}

}
</code></pre><p>Qui, la variabile <code>eta</code> è dichiarata all'interno del blocco di codice di <code>class</code>. Ciò vuol dire che puoi accedere a questa variabile all'interno di tutto il blocco <code>class</code> senza alcun problema. Dato che la variabile è accessibile nell'intera istanza di classe, è una variabile d'istanza.</p><p>Invece, le variabili <code>studenteDellaScuola</code> e <code>membroDellaLibreria</code> sono state dichiarate nel blocco di codice della prima istruzione <code>if</code>, quindi non sono accessibili fuori da quel blocco di codice.</p><p>Ma possono essere raggiunte da qualsiasi blocco di codice annidato nel primo blocco <code>if</code>. Le variabili così dichiarate sono dette variabili locali.</p><p>Esistono anche variabili di classe dichiarate con la parola chiave <code>static</code> ma avrai modo di saperne di più nelle sezioni dedicate alla programmazione orientata agli oggetti.</p><p>Per ora, la regola generale è che è possibile accedere a una variabile all'interno del blocco di codice in cui è stata dichiarata o dai blocchi in esso annidati.</p><h2 id="quali-sono-i-valori-di-default-di-una-variabile-in-java"><strong>Quali sono i valori di default di una variabile in Java?</strong></h2><p>Hai imparato che in Java hai bisogno di inizializzare una variabile dopo averla dichiarata, altrimenti non sarai in grado di usarla. Beh, non è vero in tutti i casi.</p><p>Se dichiari una variabile nel livello di classe, le verrà assegnato un valore predefinito dal compilatore.</p><pre><code class="language-java">public class Main {
	
	// impostata a 0 come valore predefinito
	static int eta;

	public static void main(String[] args) {
		System.out.println(eta); // 0
	}
}
</code></pre><p>Dato che il metodo <code>main</code> è <code>static</code>, può accedere solo a variabili <code>static</code> nel livello di classe. Parleremo di <code>static</code> molto dettagliatamente nella sezione relativa alla programmazione orientata agli oggetti.</p><p>Ma se sposti la dichiarazione della variabile all'interno del metodo <code>main</code>, diventa locale e non ottiene alcun valore predefinito.</p><pre><code class="language-java">public class Main {
	public static void main(String[] args) {
		// resta non inizializzata
		int eta;
    
		System.out.println(eta); // errore di compilazione
	}
}
</code></pre><p>Questo codice restituirà l'errore di compilazione <code>The local variable eta may not have been initialized</code>.</p><p>Alle variabili viene assegnato un valore di default in base al loro tipo. Nella maggior parte dei casi, sarà <code>0</code> o <code>null</code>. Ecco una lista dei valori predefiniti dei tipi primitivi:</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Tipo di dato</th>
<th>Valore predefinito</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>byte</code></td>
<td><code>0</code></td>
</tr>
<tr>
<td><code>short</code></td>
<td><code>0</code></td>
</tr>
<tr>
<td><code>int</code></td>
<td><code>0</code></td>
</tr>
<tr>
<td><code>long</code></td>
<td><code>0L</code></td>
</tr>
<tr>
<td><code>float</code></td>
<td><code>0.0f</code></td>
</tr>
<tr>
<td><code>double</code></td>
<td><code>0.0d</code></td>
</tr>
<tr>
<td><code>char</code></td>
<td><code>'\u0000'</code></td>
</tr>
<tr>
<td><code>boolean</code></td>
<td><code>false</code></td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><p>Ad ogni variabile di tipo riferimento sarà assegnato il valore <code>null</code> di default. Discuteremo di tipi, classi e oggetti di tipo riferimento nelle sezioni dedicate alla programmazione orientata agli oggetti.</p><h2 id="come-lavorare-con-gli-array-in-java"><strong>Come lavorare con gli array in Java</strong></h2><p>Hai già imparato come dichiarare variabili singole e usarle in un programma. Qui entrano in scena gli array.</p><p>Gli array sono strutture di dati che contengono valori multipli dello stesso tipo in posizioni di memoria sequenziali. Gli array possono essere formati da qualsiasi tipo di dati primitivi e non.</p><p>Puoi creare un array in Java in questo modo:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		// &lt;tipo&gt; &lt;nome&gt;[] = new &lt;tipo&gt;[&lt;lunghezza&gt;]
		char vocali[] = new char[5];

	}
}
</code></pre><p>Occorre scrivere il tipo di dato che l'array deve contenere, in questo caso <code>char</code>, scrivendo poi il nome dell'array, <code>vocali</code>, seguito da parentesi quadre. Le parentesi quadre comunicano a Java che stai dichiarando un array di caratteri e non una variabile carattere regolare.</p><p>Poi, bisogna aggiungere il simbolo uguale seguito dall'operatore <code>new</code>, usato per creare nuovi oggetti in Java. Dato che gli array sono di tipo riferimento in Java, <code>new</code> è necessario per creare nuove istanze.</p><p>La dichiarazione termina scrivendo di nuovo il tipo e delle parentesi quadre contenenti la lunghezza dell'array. Qui, <code>5</code> significa che l'array conterrà non più di cinque elementi.</p><p>Lavorando con una variabile singola, possiamo farvi riferimento semplicemente con il suo nome. Ma nel caso degli array, ogni elemento possiede un indicee gli array hanno indice a base zero. Questo vuol dire che il primo elemento di un array ha indice <code>0</code> e non <code>1</code>.</p><p>Per accedere a un elemento di un array, puoi scrivere il nome dell'array – in questo caso <code>vocali</code> – &nbsp;seguito dalle parentesi quadre con l'indice desiderato. Quindi se vuoi accedere al primo elemento nell'array, puoi farlo in questo modo:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		char vocali[] = new char[5];
		
		vocali[0] = 'a';
	}
}
</code></pre><p>A questo punto, <code>vocali[0]</code> è simile a una normale variabile carattere. Puoi stamparla, assegnarle un nuovo valore, svolgere calcoli nel caso di variabili di tipo numerico e così via.</p><p>Visto che l'array è vuoto al momento, assegno il carattere <code>a</code> al primo indice. Puoi assegnare il resto delle vocali agli altri indici come segue:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		char vocali[] = new char[5];
		
		vocali[0] = 'a';
		vocali[1] = 'e';
		vocali[2] = 'i';
		vocali[3] = 'o';
		vocali[4] = 'u';

	}
}
</code></pre><p>Dato che gli indici partono da <code>0</code>, l'ultimo sarà uguale alla lunghezza dell'array -1, in questo caso <code>4</code>. Se provi a assegnare altri elementi all'array, ad esempio <code>vocali[5] = 'x';</code>, il compilatore ti darà il seguente errore:</p><pre><code>Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
	at arrays.Main.main(Main.java:18)
</code></pre><p>Gli array non possono essere stampati come le variabili normali. Occorre usare un loop oppure convertire l'array in una stringa. Visto che non abbiamo ancora parlato dei loop, userò il secondo metodo.</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {
		char vocali[] = new char[5];
		
		vocali[0] = 'a';
		vocali[1] = 'e';
		vocali[2] = 'i';
		vocali[3] = 'o';
		vocali[4] = 'u';
		
		System.out.println("Le vocali sono: " + Arrays.toString(vocali));

	}
}
</code></pre><p>Dovrai prima importare <code>java.util.Arrays;</code> e usare il metodo <code>Arrays.toString()</code> per convertire l'array in una stringa. Questa classe possiede altri metodi interessanti, ma prima di parlane, vorrei mostrarti come dichiarare e inizializzare un array in un colpo solo.</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {
		char vocali[] = {'a', 'e', 'i', 'o', 'u'};
		
		System.out.println("Le vocali sono: " + Arrays.toString(vocali));

	}
}
</code></pre><p>La parte sinistra della dichiarazione resta invariata, mentre, dopo l'operatore di assegnazione, invece di usare <code>new</code> dovrai scrivere i singoli elementi dell'array separati da una virgola all'interno delle parentesi graffe.</p><p>In questo caso il compilatore conterà gli elementi dell'array e utilizzerà questo conteggio come lunghezza dell'array.</p><p>Se non conosci la lunghezza di un array, puoi usare la proprietà <code>length</code>.</p><p>In questo caso, <code>vocali.length</code> sarà <code>5</code>, visto che ci sono cinque elementi nell'array. La proprietà <code>length</code> dà un intero ed è utilizzabile per ogni array in Java.</p><p>Gli array possono anche essere multidimensionali. Finora abbiamo lavorato con array come questo:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/08/single-dimensional-array.svg" class="kg-image" alt="single-dimensional-array" width="600" height="400" loading="lazy"></figure><p>Gli array monodimensionali sono ideali per contenere una serie di valori. Ma immagina un piano terapeutico giornaliero in forma di una tabella:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/08/multi-dimensional-array-1.svg" class="kg-image" alt="multi-dimensional-array-1" width="600" height="400" loading="lazy"></figure><p>La prima riga rappresenta i sette giorni della settimana e le colonne rappresentano quante volte un paziente deve prendere un farmaco durante tre momenti della giornata. <code>0</code> vuol dire no e <code>1</code> vuol dire sì.</p><p>Puoi descrivere questa routine giornaliera usando un array multidimensionale:</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {		
		int pianoTerapeutico[][] = {
				{1, 2, 3, 4, 5, 6, 7},
				{0, 1, 1, 0, 1, 1, 0},
				{1, 0, 1, 0, 1, 0, 0},
				{0, 0, 1, 1, 0, 1, 0},
		};
		
		System.out.println(Arrays.deepToString(pianoTerapeutico)); // [[1, 2, 3, 4, 5, 6, 7], [0, 1, 1, 0, 1, 1, 0], [1, 0, 1, 0, 1, 0, 0], [0, 0, 1, 1, 0, 1, 0]]

	}
}
</code></pre><p>Gli array multidimensionali non possono essere stampati con il normale metodo <code>Arrays.toString()</code>, devi scavare più a fondo.</p><p>Anche se l'output non sembra proprio una tabella, puoi renderlo simile a una tabella con un po' di codice:</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {		
		int pianoTerapeutico[][] = {
				{1, 2, 3, 4, 5, 6, 7},
				{0, 1, 1, 0, 1, 1, 0},
				{1, 0, 1, 0, 1, 0, 0},
				{0, 0, 1, 1, 0, 1, 0},
		};
		
		System.out.println(Arrays.deepToString(pianoTerapeutico).replace("], ", "]\n"));
	}
}

// [[1, 2, 3, 4, 5, 6, 7]
// [0, 1, 1, 0, 1, 1, 0]
// [1, 0, 1, 0, 1, 0, 0]
// [0, 0, 1, 1, 0, 1, 0]]</code></pre><p>Hai già imparato a usare il metodo <code>replace()</code> per le stringhe. Qui, stiamo semplicemente sostituendo la parentesi finale in ogni riga con una parentesi e il carattere nuova riga.</p><p>La prima riga rappresenta i 7 giorni della settimana e il resto delle righe le medicina da prendere ogni giorno. Ogni riga della tabella è un array.</p><p>Per accedere a un singolo valore di un array multidimensionale ti servono due indici. Il primo indice determina la riga e il secondo la colonna.</p><p>Quindi <code>pianoTerapeutico[2][3]</code> selezionerà l'elemento di indice <code>3</code> del terzo array, che sarà <code>0</code>. Lavorare con array multidimensionali può sembrare un po' complesso ma con la pratica diventa più semplice.</p><p>Visto che in Java puoi creare array di ogni tipo, perché non provi a creare altri tipi di array da solo?</p><h3 id="come-ordinare-un-array"><strong>Come ordinare un array</strong></h3><p>Una delle operazioni più comuni che puoi eseguire su un array è ordinarlo. <code>java.utils.Arrays</code> con il metodo <code>Arrays.sort()</code> è qui proprio per questo:</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {		
		char vocali[] = {'e', 'u', 'o', 'i', 'a'};
		
		Arrays.sort(vocali);
		
		System.out.println("L'array ordinato è: " + Arrays.toString(vocali)); // [a, e, i, o , u]

	}
}
</code></pre><p>Il metodo <code>Arrays.sort()</code> accetta un array non ordinato come argomento e lo riordina. Quindi invece di ottenere un nuovo array ordinato, l'array originale viene ordinato in ordine ascendente.</p><p>Di default, il metodo tratta il primo indice dell'array come indice di partenza e la lunghezza dell'array come indice finale.</p><p>Puoi specificare i due indici manualmente. Ad esempio, se vuoi ordinare soltanto <code>u, o, i</code> in ordine ascendente e lasciare <code>e, a</code> come sono, puoi farlo in questo modo:</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {		
		char vocali[] = {'e', 'u', 'o', 'i', 'a'};
		
		int indicePartenza = 1;
		int indiceFine = 4;
		
		Arrays.sort(vocali, indicePartenza, indiceFine);
		
		System.out.println("L'array ordinato è: " + Arrays.toString(vocali)); // [e, i, o, u , a]

	}
}
</code></pre><p>Stavolta, il metodo prende l'array come primo parametro, l'indice di partenza come secondo parametro e quello di fine come terzo parametro. Il resto rimane invariato.</p><h3 id="come-eseguire-una-ricerca-binaria-su-un-array"><strong>Come eseguire una ricerca binaria su un array</strong></h3><p>Cercare dei valori in un array ordinato è un'operazione comune. Il metodo <code>Arrays.binarySearch()</code> ti permette di cercare degli elementi all'interno di un array ordinato usando l'algoritmo di ricerca binaria.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		char vocali[] = {'a', 'e', 'i', 'o', 'u'};
        
        char chiave = 'i';
		
		int trovaIndiceElemento = Arrays.binarySearch(vocali, chiave);
		
		System.out.println("La vocale 'i' è all'indice: " + trovaIndiceElemento); // 2

	}
}
</code></pre><p>Il metodo <code>Arrays.binarySearch()</code> prende come primo parametro un array e la chiave di ricerca (l'elemento che stiamo cercando) come secondo parametro, per poi restituire l'indice dell'elemento desiderato come un intero.</p><p>Puoi memorizzare l'indice in un <code>int</code> e usarlo per accedere all'elemento dell'array con <code>vocali[trovaIndiceElemento]</code>.</p><p>Nota che l'array è stato ordinato in modo ascendente. Se non sei sicuro dell'ordine dell'array, usa prima il metodo <code>Arrays.sort()</code> per ordinarlo.</p><p>Di default, il metodo tratta il primo indice dell'array come punto di partenza e la lunghezza dell'array come termine, ma puoi specificare gli indici manualmente.</p><p>Ad esempio, se vuoi che la ricerca avvenga dall'indice <code>2</code> all'indice <code>4</code>, puoi farlo così:</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {
		char vocali[] = {'a', 'e', 'i', 'o', 'u'};
        
        char chiave = 'i';
		int indicePartenza = 2;
		int indiceFine = 4;
		
		int trovaIndiceElemento = Arrays.binarySearch(vocali, indicePartenza, indiceFine, chiave);
		
		System.out.println("La vocale 'i' è all'indice: " + trovaIndiceElemento); // 2

	}
}
</code></pre><p>Stavolta il metodo prende l'array su cui vuoi effettuare la ricerca come primo parametro, l'indice di partenza come secondo, l'indice finale come terzo e la chiave di ricerca come quarto parametro.</p><p>Ora, la ricerca avverrà tra <code>i</code>, <code>o</code> e <code>u</code>. &nbsp;Quindi, se cerchi la <code>a</code>, non la troverai. In casi in cui l'elemento dato non viene trovato, otterrai un indice negativo, variabile a seconda di una serie di fattori che non discuterò qui. Se sei interessato a saperne di più, dai un'occhiata a <a href="https://www.freecodecamp.org/news/how-to-use-arrays-binarysearch-in-java/"></a><a href="https://www.freecodecamp.org/italian/news/come-usare-arrays-binarysearch-in-java/">questo articolo sull'argomento</a>. </p><h3 id="come-riempire-un-array"><strong>Come riempire un array</strong></h3><p>Hai già imparato come inizializzare un array con dei valori, ma a volte potresti aver bisogno di riempire un intero array con lo stesso valore. Il metodo <code>Arrays.fill()</code> può farlo per te:</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {		
		char vocali[] = {'e', 'u', 'o', 'i', 'a'};
		
		Arrays.fill(vocali, 'x');
		
		System.out.println("L'array riempito: " + Arrays.toString(vocali)); // [x, x, x, x, x]

	}
}
</code></pre><p>Come il metodo <code>Arrays.sort()</code>, <code>Arrays.fill()</code> può eseguire altre operazioni. Prende l'array come primo parametro, il valore che vuoi inserire come secondo parametro e aggiorna l'array originale in loco.</p><p>Anche questo metodo tratta il primo indice come punto di partenza e la lunghezza come indice finale. Puoi specificare questi indici manualmente come segue:</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {		
		char vocali[] = {'e', 'u', 'o', 'i', 'a'};
		
		int indicePartenza = 1;
		int indiceFine = 4;
		
		Arrays.fill(vocali, indicePartenza, indiceFine, 'x');
		
		System.out.println("L'array riempito: " + Arrays.toString(vocali)); // [e, x, x, x, a]

	}
}
</code></pre><p>In questo caso, il metodo prende l'array come primo argomento, l'indice di partenza come secondo, l'indice finale come terzo e il valore da inserire come quarto argomento.</p><h3 id="come-fare-una-copia-di-un-array"><strong>Come fare una copia di un array</strong></h3><p>Dato che in Java gli array sono di tipo riferimento, copiarli usando l'operatore di assegnazione può causare qualche comportamento inatteso.</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {
		int numeriDispari[] = {1, 3, 5};
		int copiaNumeriDispari[] = numeriDispari;
		
		Arrays.fill(numeriDispari, 0);
		
		System.out.println("L'array copiato: " + Arrays.toString(copiaNumeriDispari)); // [0, 0, 0]

	}
}
</code></pre><p>I cambiamenti apportati all'array sorgente si riflettono anche sulla copia. Questo accade perché &nbsp;quando usiamo l'operatore di assegnazione per copiare l'array, la copia fa riferimento all'array originale in memoria.</p><p>Per copiare un array in modo appropriato, puoi usare il metodo <code>Arrays.copyOf()</code> come segue:</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {
		int numeriDispari[] = {1, 3, 5};
		int copiaNumeriDispari[] = Arrays.copyOf(numeriDispari, numeriDispari.length);
		
		Arrays.fill(numeriDispari, 0);
		
		System.out.println("L'array copiato: " + Arrays.toString(copiaNumeriDispari)); // [1, 3, 5]

	}
}
</code></pre><p>Il metodo prende l'array sorgente come primo argomento e la lunghezza del nuovo array come secondo argomento. Se vuoi che la lunghezza sia la stessa, passa semplicemente la lunghezza dell'array originale usando la proprietà <code>length</code>.</p><p>Se inserisci una lunghezza minore, ogni valore successivo sarà escluso e se inserisci una lunghezza maggiore, i nuovi indici saranno popolati con il valore di default per il tipo di dato nell'array.</p><p>Esiste anche &nbsp;il metodo <code>Arrays.copyOfRange()</code> che può copiare una porzione di un array in un nuovo array:</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {
		int numeriDispari[] = {1, 3, 5, 7, 9, 11, 13, 15};
		
		int indicePartenza = 2;
		int indiceFine = 7;
		
		int copiaNumeriDispari[] = Arrays.copyOfRange(numeriDispari, indicePartenza, indiceFine);
		
		System.out.println("L'array copiato: " + Arrays.toString(copiaNumeriDispari)); // [5, 7, 9, 11, 13]

	}
}
</code></pre><p>Questo metodo prende l'array sorgente come primo argomento, seguito dall'indice di partenza e di fine.</p><p>Tieni a mente che l'indice finale non è incluso. Ecco perché il 15 non è presente nel nuovo array. Ma se vuoi includere l'ultimo indice dell'array, usa la lunghezza dell'array originale come indice finale.</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {
		int numeriDispari[] = {1, 3, 5, 7, 9, 11, 13, 15};
		
		int indicePartenza = 2;
		int indiceFine = numeriDispari.length;
		
		int copiaNumeriDispari[] = Arrays.copyOfRange(numeriDispari, indicePartenza, indiceFine);
		
		System.out.println("L'array copiato: " + Arrays.toString(copiaNumeriDispari)); // [5, 7, 9, 11, 13, 15]

	}
}
</code></pre><p>Ora il nuovo array includerà anche il 15. Puoi anche inserire un numero può grande della lunghezza dell'array sorgente. In questo caso, i nuovi indici aggiunti conterranno il valore di default del tipo di dato nell'array.</p><h3 id="come-confrontare-due-array"><strong>Come confrontare due array</strong></h3><p>Se propri a verificare se due array sono uguali o meno in Java usando l'operatore di uguaglianza relazionale, otterrai dei risultati inaspettati.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {		
		int numeriDispari1[] = {1, 3, 5, 7, 9, 11, 13, 15};
		int numeriDispari2[] = {1, 3, 5, 7, 9, 11, 13, 15};
		
		System.out.println(numeriDispari1 == numeriDispari2); // false
	}
}
</code></pre><p>Anche se i due array sono identici, l'output del programma è <code>false</code>. Visto che gli array sono di tipo riferimento, l'operatore di confronto verificherà se sono la stessa istanza o no.</p><p>Per confrontare due array in Java, puoi usare il metodo <code>Arrays.equals()</code>:</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {		
		int numeriDispari1[] = {1, 3, 5, 7, 9, 11, 13, 15};
		int numeriDispari2[] = {1, 3, 5, 7, 9, 11, 13, 15};
		
		System.out.println(Arrays.equals(numeriDispari1, numeriDispari2)); // true
	}
}
</code></pre><p>Tuttavia, se cambi anche un solo elemento in questi array, l'output sarà <code>false</code> dato gli array non saranno più uguali.</p><p>Puoi anche confrontare array multidimensionali, ma per quello devi utilizzare il metodo <code>Arrays.deepEquals()</code> invece del metodo usuale.</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {		
		int pianoTerapeutico1[][] = {
				{1, 2, 3, 4, 5, 6, 7},
				{0, 1, 1, 0, 1, 1, 0},
				{1, 0, 1, 0, 1, 0, 0},
				{0, 0, 1, 1, 0, 1, 0},
		};
		
		int pianoTerapeutico2[][] = {
				{1, 2, 3, 4, 5, 6, 7},
				{0, 1, 1, 0, 1, 1, 0},
				{1, 0, 1, 0, 1, 0, 0},
				{0, 0, 1, 1, 0, 1, 0},
		};
		
		System.out.println(Arrays.deepEquals(pianoTerapeutico1, pianoTerapeutico2)); // true
	}
}
</code></pre><p>Questo metodo chiama sé stesso ogni volta che incontra un nuovo array all'interno dell'array genitore.</p><p>Questi erano i metodi più comuni all'interno della classe <code>java.util.Arrays</code>. Se vuoi impararne altri, consulta la <a href="https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html">documentazione ufficiale</a>.</p><h2 id="come-usare-i-loop-in-java"><strong>Come usare i loop in Java</strong></h2><p>Se hai bisogno di ripetere un'operazione per un certo numero di volte, puoi usare un loop. I loop possono essere di tre tipi: loop <code>for</code>, loop <code>for...each</code> e loop <code>while</code>.</p><h3 id="loop-for"><strong>Loop for</strong></h3><p>I loop <code>for</code> sono probabilmente il tipo di loop più comune che troverai su internet.</p><p>Ogni loop <code>for</code> è formato da tre parti. L'inizializzazione, la condizione e un'espressione di aggiornamento. Le iterazioni avvengono in più passaggi.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/08/for-loop-generic-2.svg" class="kg-image" alt="for-loop-generic-2" width="600" height="400" loading="lazy"></figure><p>Se vuoi stampare i numeri da 0 a 10 usando un loop <code>for</code>, puoi farlo in questo modo:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		for (int number = 0; number &lt;= 10; number++) {
			System.out.println(number);
		}
	}
}

// 0
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
// 10</code></pre><p>Il diagramma a flusso di questo loop sarà il seguente:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/08/for-loop-number-1.svg" class="kg-image" alt="for-loop-number-1" width="600" height="400" loading="lazy"></figure><ol><li>All'inizio del loop, inizializziamo un nuovo intero chiamato <code>number</code> con il valore iniziale <code>0</code>.</li><li>Poi, viene verificato se <code>number</code> è minore o uguale a <code>10</code> oppure no.</li><li>Se è minore o uguale a <code>10</code>, l'istruzione all'interno del blocco del loop viene eseguita e il valore della variabile stampato sul terminale.</li><li>Poi, la variabile è aggiornata, incrementandone il valore di 1.</li><li>Il loop torna indietro per verificare se il valore di <code>number</code> è ancora minore o uguale a <code>10</code> oppure no.</li></ol><p>Finché il valore di <code>number</code> resta minore o uguale a <code>10</code>, il loop prosegue. Nel momento in cui il suo valore diventa <code>11</code>, il loop termina.</p><p>Puoi usare un loop <code>for</code> per iterare su un array, in questo modo:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int serieFibonacci[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55};
		
		for(int index = 0; index &lt; serieFibonacci.length; index++) {
			System.out.println(serieFibonacci[index]);
		}
	}
}
</code></pre><p>Il diagramma di flusso di questo loop sarà:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/08/for-loop-fibo.svg" class="kg-image" alt="for-loop-fibo" width="600" height="400" loading="lazy"></figure><p>Dato che l'ultimo indice dell'array è minore della sua lunghezza, il loop viene eseguito per tutti gli elementi dell'array. Nel momento in cui il valore di <code>index</code> diventa uguale alla lunghezza dell'array, usciamo dal loop.</p><p>Una delle cose simpatiche che puoi fare con i loop è stampare tabelline di moltiplicazione. Ad esempio, la tabellina del 5:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int numero = 5;
		
		for (int moltiplicatore = 1; moltiplicatore &lt;= 10; moltiplicatore++) {
			System.out.println(String.format("%d x %d = %d", numero, moltiplicatore, numero * moltiplicatore));
		}
	}
}

// 5 x 1 = 5
// 5 x 2 = 10
// 5 x 3 = 15
// 5 x 4 = 20
// 5 x 5 = 25
// 5 x 6 = 30
// 5 x 7 = 35
// 5 x 8 = 40
// 5 x 9 = 45
// 5 x 10 = 50</code></pre><p>I loop possono anche essere annidati. Ciò vuol dire che puoi inserire un loop in un altro loop. Possiamo stampare le tabelline dei numeri da 1 a 10 usando dei loop annidati:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		for (int numero = 1; numero &lt;= 10; numero++) {
			System.out.println(String.format("\ntabellina del %d", numero));
			for (int moltiplicatore = 1; moltiplicatore &lt;= 10; moltiplicatore++) {
				System.out.println(String.format("%d x %d = %d", numero, moltiplicatore, numero * moltiplicatore));
			}
		}
	}
}
</code></pre><p>Non aggiungo l'output di questo codice. Provalo tu stesso e scrivi le iterazioni del loop su carta in modo da capire meglio cosa accade in ogni passaggio.</p><h3 id="loop-for-each"><strong>Loop for-each</strong></h3><p>Se vuoi iterare su un insieme come un array e svolgere delle operazioni su ogni elemento dell'insieme, puoi usare un loop for-each.</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int serieFibonacci[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55};
		
		for(int numero : serieFibonacci) {
			System.out.println(numero);
		}
	}
}
</code></pre><p>Nel caso di un loop for-each, il tipo di elemento deve corrispondere al tipo di elementi dell'insieme con cui stai lavorando. Qui, l'array è di tipo <code>int</code> e quindi anche l'elemento del loop è un intero.</p><p>Questo loop svolge esattamente le stesse operazioni viste in precedenza, ma stavolta, non devi tenere traccia dell'indice o usare le parentesi quadre per accedere agli elementi. Ha un aspetto più pulito ed è meno favorevole alla generazione di errori.</p><h3 id="loop-while"><strong>Loop <code>while</code></strong></h3><p>Se vuoi eseguire un gruppo di codice finché una determinata condizione è verificata, puoi usare un loop <code>while</code>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/08/while-loop-generic.svg" class="kg-image" alt="while-loop-generic" width="600" height="400" loading="lazy"></figure><p>Non ci sono passaggi di inizializzazione o aggiornamento in un loop <code>while</code>. Accade tutto nel corpo del loop. Se riscriviamo il programma per stampare la tabellina del 5 usando un loop <code>while</code> in questo modo:</p><pre><code>public class Main {

	public static void main(String[] args) {
		int numero = 5;
		int moltiplicatore = 1;
		
		while (moltiplicatore &lt;= 10) {
			System.out.println(String.format("%d x %d = %d", numero, moltiplicatore, numero*moltiplicatore));
			
			moltiplicatore++;
		}
	}
}

// 5 x 1 = 5
// 5 x 2 = 10
// 5 x 3 = 15
// 5 x 4 = 20
// 5 x 5 = 25
// 5 x 6 = 30
// 5 x 7 = 35
// 5 x 8 = 40
// 5 x 9 = 45
// 5 x 10 = 50</code></pre><p>Anche se i loop <code>while</code> sono meno comuni dei loop <code>for</code>, è bene imparare a utilizzarli.</p><h3 id="loop-do-while"><strong>Loop <code>do</code>-<code>while</code></strong></h3><p>L'ultimo tipo di loop di cui parleremo è il loop <code>do</code>-<code>while</code>. Inverte il normale ordine delle operazioni di un loop <code>while</code> – quindi invece di controllare prima la condizione e poi eseguire il corpo del loop, esegue prima il corpo del loop e poi verifica la condizione.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/08/do-while-loop-generic.svg" class="kg-image" alt="do-while-loop-generic" width="600" height="400" loading="lazy"></figure><p>Il codice per stampare la tabellina del 5 implementato con un loop <code>do</code>-<code>while</code> sarà:</p><pre><code class="language-java">public class Main {

	public static void main(String[] args) {
		int numero = 5;
		int moltiplicatore = 1;
		
		do {
			System.out.println(String.format("%d x %d = %d", numero, moltiplicatore, numero*moltiplicatore));
			
			moltiplicatore++;
		} while (moltiplicatore &lt;= 10);
	}
}

// 5 x 1 = 5
// 5 x 2 = 10
// 5 x 3 = 15
// 5 x 4 = 20
// 5 x 5 = 25
// 5 x 6 = 30
// 5 x 7 = 35
// 5 x 8 = 40
// 5 x 9 = 45
// 5 x 10 = 50</code></pre><p>Questo tipo di loop è molto utile quando hai bisogno di svolgere alcune operazioni finché un utente non ti dà un input specifico. Come mostrare un menu finché l'utente preme il tasto "x".</p><h2 id="come-lavorare-con-gli-arraylist-in-java"><strong>Come lavorare con gli ArrayList in Java</strong></h2><p>In Java, gli array non sono ridimensionabili. Una volta che hai impostato una lunghezza per un array non puoi cambiarla in nessun modo. In Java, la classe <code>ArrayList</code> rimedia a questa limitazione.</p><pre><code class="language-java">import java.util.ArrayList;

public class Main {
    public static void main (String[] args) {
        ArrayList&lt;Integer&gt; numeriDispari = new ArrayList&lt;&gt;();

        numeriDispari.add(1);
        numeriDispari.add(3);
        numeriDispari.add(5);
        numeriDispari.add(7);
        numeriDispari.add(9);

        System.out.println(numeriDispari.toString()); // [1, 3, 5, 7, 9]
    }
}

</code></pre><p>Per creare un ArrayList, devi importare la classe <code>java.util.ArrayList</code> in cima al tuo file sorgente.</p><p>Poi, devi scrivere <code>ArrayList</code>, il tipo di dato degli elementi all'interno di parentesi angolate, aggiungere il numero dell'ArrayList seguito dall'operatore di assegnazione e <code>new ArrayList&lt;&gt;()</code>.</p><p>Non puoi creare ArrayList di tipo primitivo, quindi dovrai usare le classi wrapper corrispondenti.</p><p>Anche se questi elementi hanno indice a base zero come gli array, non puoi utilizzare la notazione con parentesi quadre per accedervi. Invece, occorre usare il metodo <code>get()</code>:</p><pre><code class="language-java">import java.util.ArrayList;

public class Main {
    public static void main (String[] args) {
        ArrayList&lt;Integer&gt; numeriDispari = new ArrayList&lt;&gt;();

        numeriDispari.add(1);
        numeriDispari.add(3);
        numeriDispari.add(5);
        numeriDispari.add(7);
        numeriDispari.add(9);

        System.out.println(numeriDispari.get(2)); // 5
    }
}</code></pre><p>Il metodo <code>get()</code> ti darà il valore presente all'indice dato. Allo stesso modo di <code>get()</code>, puoi usare il metodo <code>set()</code> per aggiornare il valore di un elemento.</p><pre><code class="language-java">import java.time.LocalDate;
import java.util.ArrayList;

public class Main {
    public static void main (String[] args) {
        ArrayList&lt;Integer&gt; numeriDispari = new ArrayList&lt;&gt;();

        numeriDispari.add(1);
        numeriDispari.add(3);
        numeriDispari.add(5);
        numeriDispari.add(7);
        numeriDispari.add(9);

        numeriDispari.set(2, 55);

        System.out.println(numeriDispari.get(2)); // 55
    }
}</code></pre><p>Il primo parametro del metodo <code>set()</code> è l'indice e il secondo è il valore aggiornato.</p><p>Non esiste una proprietà <code>length</code> come per gli array ma puoi usare il metodo <code>size()</code> su qualsiasi ArrayList per trovarne la lunghezza.</p><pre><code>import java.util.ArrayList;

public class Main {
    public static void main (String[] args) {
        ArrayList&lt;Integer&gt; numeriDispari = new ArrayList&lt;&gt;();

        numeriDispari.add(1);
        numeriDispari.add(3);
        numeriDispari.add(5);
        numeriDispari.add(7);
        numeriDispari.add(9);

        System.out.println(numeriDispari.size()); // 5
    }
}</code></pre><p>Puoi rimuovere elementi da un ArrayList usando il metodo <code>remove()</code>:</p><pre><code class="language-java">import java.util.ArrayList;

public class Main {
    public static void main (String[] args) {
        ArrayList&lt;Integer&gt; numeriDispari = new ArrayList&lt;&gt;();

        numeriDispari.add(1);
        numeriDispari.add(3);
        numeriDispari.add(5);
        numeriDispari.add(7);
        numeriDispari.add(9);

        numeriDispari.remove(Integer.valueOf(7));
        numeriDispari.remove(Integer.valueOf(9));

        System.out.println(numeriDispari.toString()); // [1, 3, 5]
    }
}

</code></pre><p>Il metodo <code>remove()</code> può rimuovere un elemento in base al suo valore o al suo indice. Se passi al metodo un valore intero primitivo, rimuoverà l'elemento corrispondente a quell'indice.</p><p>Ma se passi un oggetto, come in questo codice, il metodo troverà e cancellerà l'elemento dato. Il metodo <code>valueOf()</code> è presente in tutte le classi wrapper e può convertire un valore primitivo in un tipo riferimento.</p><h3 id="come-aggiungere-o-rimuovere-elementi-multipli"><strong>Come aggiungere o rimuovere elementi multipli</strong></h3><p>Abbiamo già visto esempi dei metodi <code>add()</code> e <code>remove()</code>, ma esistono anche i metodi <code>addAll()</code> e <code>removeAll()</code> per lavorare con elementi multipli.</p><pre><code class="language-java">import java.util.ArrayList;

public class Main {
    public static void main (String[] args) {
        ArrayList&lt;Integer&gt; numeriDispari = new ArrayList&lt;&gt;();

        numeriDispari.add(1);
        numeriDispari.add(3);
        numeriDispari.add(5);

        ArrayList&lt;Integer&gt; altriNumeriDispari = new ArrayList&lt;&gt;();

        altriNumeriDispari.add(7);
        altriNumeriDispari.add(9);
        altriNumeriDispari.add(11);

        numeriDispari.addAll(altriNumeriDispari); // [1, 3, 5, 7, 9, 11]

        System.out.println(numeriDispari.toString());

        numeriDispari.removeAll(altriNumeriDispari);

        System.out.println(numeriDispari.toString()); // [1, 3, 5]
    }
}

</code></pre><p>Entrambi i metodi accettano delle collezioni come parametri. Nel codice qui sopra, abbiamo creato due ArrayList separati per poi unirli con il metodo <code>addAll()</code>.</p><p>In seguito abbiamo rimosso gli elementi del secondo ArrayList usando il metodo <code>removeAll()</code> per far tornare l'ArrayList nel suo stato originario.</p><p>Puoi anche eliminare tutti gli elementi di un ArrayList con il metodo <code>clear()</code>:</p><pre><code class="language-java">import java.util.ArrayList;

public class Main {
    public static void main (String[] args) {
        ArrayList&lt;Integer&gt; numeriDispari = new ArrayList&lt;&gt;();

        numeriDispari.add(1);
        numeriDispari.add(3);
        numeriDispari.add(5);

        numeriDispari.clear();
        
        System.out.println(numeriDispari.toString()); // []
    }
}</code></pre><p>Il metodo non richiede nessun parametro e non restituisce nessun valore. Svuota semplicemente l'ArrayList con una sola chiamata.</p><h3 id="come-rimuovere-elementi-in-base-a-una-condizione"><strong>Come rimuovere elementi in base a una condizione</strong></h3><p>Il metodo <code>removeIf()</code> può essere usato per rimuovere elementi da un ArrayList in base a una condizione:</p><pre><code class="language-java">import java.util.ArrayList;

public class Main {
    public static void main (String[] args) {
        ArrayList&lt;Integer&gt; numeri = new ArrayList&lt;&gt;();

        for (int i = 0; i &lt;= 10; i++) {
            numeri.add(i);
        }

        System.out.println(numeri.toString()); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

        numeri.removeIf(numero -&gt; numero % 2 == 1);

        System.out.println(numeri.toString()); // [0, 2, 4, 6, 8, 10]
    }
}</code></pre><p>Il metodo accetta un'espressione lambda come parametro. Le espressioni lambda sono dei metodi senza nome, che ricevono dei parametri e svolgono delle operazioni su di essi.</p><p>In questo caso, il metodo <code>removeIf()</code> itera sull'ArrayList e passa ogni elemento all'espressione lambda come valore della variabile <code>numero</code>.</p><p>Poi l'espressione lambda verifica se il numero dato è divisibile per 2 oppure no e restituisce <code>true</code> o <code>false</code> in base al risultato.</p><p>Se l'espressione lambda restituisce <code>true</code>, il metodo <code>removeIf()</code> conserverà il valore, altrimenti lo cancellerà.</p><h3 id="come-clonare-e-confrontare-degli-arraylist"><strong>Come clonare e confrontare degli ArrayList</strong></h3><p>Per duplicare un ArrayList puoi usare il metodo <code>clone()</code>:</p><pre><code class="language-java">import java.util.ArrayList;

public class Main {
    public static void main (String[] args) {
        ArrayList&lt;Integer&gt; numeri = new ArrayList&lt;&gt;();

        for (int i = 0; i &lt;= 10; i++) {
            numeri.add(i);
        }

        ArrayList&lt;Integer&gt; numeriClonato = (ArrayList&lt;Integer&gt;)numeri.clone();

        System.out.println(numeriClonato.equals(numeri)); // true
    }
}

</code></pre><p>Il metodo <code>clone()</code> restituisce un oggetto, quindi occorre definire correttamente il tipo dell'ArrayList manualmente. Puoi confrontare due ArrayList con il metodo <code>equals()</code>, proprio come per gli array.</p><h3 id="come-verificare-la-presenza-di-un-elemento-e-se-un-arraylist-vuoto"><strong>Come verificare la presenza di un elemento e se un ArrayList è vuoto</strong></h3><p>Puoi usare il metodo <code>contains()</code> per controllare se un ArrayList contiene o meno un dato elemento:</p><pre><code class="language-java">import java.util.ArrayList;

public class Main {
    public static void main (String[] args) {
        ArrayList&lt;Integer&gt; numeriDispari = new ArrayList&lt;&gt;();

        numeriDispari.add(1);
        numeriDispari.add(3);
        numeriDispari.add(5);
        numeriDispari.add(7);
        numeriDispari.add(9);

        System.out.println(numeriDispari.isEmpty()); // false
        System.out.println(numeriDispari.contains(5)); // true
    }
}</code></pre><p>Se vuoi verificare se un ArrayList è vuoto oppure no, chiama semplicemente il metodo <code>isEmpty()</code> e otterrai un booleano come valore di ritorno.</p><h3 id="come-ordinare-un-arraylist"><strong>Come ordinare un ArrayList</strong></h3><p>Puoi ordinare un ArrayList in diversi modi usando il metodo <code>sort()</code>:</p><pre><code class="language-java">import java.util.ArrayList;
import java.util.Comparator;

public class Main {
    public static void main (String[] args) {
        ArrayList&lt;Integer&gt; numeriDispari = new ArrayList&lt;&gt;();

        numeriDispari.add(5);
        numeriDispari.add(7);
        numeriDispari.add(1);
        numeriDispari.add(9);
        numeriDispari.add(3);

        System.out.println(numeriDispari.toString()); [5, 7, 1, 9, 3]

        numeriDispari.sort(Comparator.naturalOrder());

        System.out.println(numeriDispari.toString()); [1, 3, 5, 7, 9]
    }
}</code></pre><p>Il metodo <code>sort()</code> prende come parametro un comparator che impone l'ordine sull'ArrayList.</p><p>Puoi riordinare l'ArrayList in ordine inverso cambiando il comparator passato:</p><pre><code class="language-java">import java.util.ArrayList;
import java.util.Comparator;

public class Main {
    public static void main (String[] args) {
        ArrayList&lt;Integer&gt; numeriDispari = new ArrayList&lt;&gt;();

        numeriDispari.add(5);
        numeriDispari.add(7);
        numeriDispari.add(1);
        numeriDispari.add(9);
        numeriDispari.add(3);

        System.out.println(numeriDispari.toString()); // [5, 7, 1, 9, 3]

        numeriDispari.sort(Comparator.reverseOrder());

        System.out.println(numeriDispari.toString()); // [9, 7, 5, 3, 1]
    }
}</code></pre><p>I comparator hanno anche altri utilizzi, ma questi vanno oltre lo scopo di questo manuale.</p><h3 id="come-tenere-gli-elementi-comuni-in-due-arraylist"><strong>Come tenere gli elementi comuni in due ArrayList</strong></h3><p>Immagina di avere due ArrayList e di dover trovare quali elementi sono presenti in entrambi, rimuovendo gli altri dal primo ArrayList.</p><pre><code class="language-java">import java.util.ArrayList;

public class Main {
    public static void main (String[] args) {
        ArrayList&lt;Integer&gt; numeriDispari = new ArrayList&lt;&gt;();

        numeriDispari.add(1);
        numeriDispari.add(3);
        numeriDispari.add(5);

        ArrayList&lt;Integer&gt; altriNumeriDispari = new ArrayList&lt;Integer&gt;();

        altriNumeriDispari.add(5);
        altriNumeriDispari.add(7);
        altriNumeriDispari.add(9);

        numeriDispari.retainAll(altriNumeriDispari);

        System.out.println(numeriDispari.toString()); // [5]
    }
}</code></pre><p>Il metodo <code>retainAll()</code> può sbarazzarsi per te degli elementi non comuni ai due ArrayList. Dovrai chiamare il metodo sull'ArrayList su cui vuoi operare e passare l'altro ArrayList come parametro.</p><h3 id="come-eseguire-un-azione-su-tutti-gli-elementi-di-un-arraylist"><strong>Come eseguire un'azione su tutti gli elementi di un ArrayList</strong></h3><p>Hai già imparato come usare i loop nelle sezioni precedenti. Bene, gli ArrayList possiedono già un metodo <code>forEach()</code> che accetta un'espressione lambda come parametro e può svolgere un'azione su tutti gli elementi dell'ArrayList.</p><pre><code class="language-java">import java.util.ArrayList;

public class Main {
    public static void main (String[] args) {
        ArrayList&lt;Integer&gt; numeriDispari = new ArrayList&lt;&gt;();

        numeriDispari.add(1);
        numeriDispari.add(3);
        numeriDispari.add(5);
        numeriDispari.add(7);
        numeriDispari.add(9);

        numeriDispari.forEach(numero -&gt; {
            numero = numero * 2;
            System.out.printf("%d ", numero); // 2 6 10 14 18
        });

        System.out.println(numeriDispari.toString()); // [1, 3, 5, 7, 9]
    }
}</code></pre><p>L'ultima volta, l'espressione lambda che abbiamo visto era su una singola riga – ma ce ne possono essere di più grandi. Qui, il metodo <code>forEach()</code> itererà sull'ArrayList passando ogni elemento all'espressione lambda come valore della variabile <code>numero</code>.</p><p>L'espressione lambda moltiplicherà il valore fornito per 2 e lo stamperà sul terminale. Tuttavia, l'ArrayList originario resterà invariato.</p><h2 id="come-lavorare-con-le-hashmap-in-java"><strong>Come lavorare con le HashMap in Java</strong></h2><p>In Java, le HashMap possono contenere elementi in coppie chiave-valore. Questo tipo di collezioni è comparabile ai dizionari in Python o agli oggetti in JavaScript.</p><pre><code class="language-java">import java.util.HashMap;

public class Main {
    public static void main (String[] args) {
        HashMap&lt;String, Double&gt; prezzi = new HashMap&lt;&gt;();

        prezzi.put("mela", 2.0);
        prezzi.put("arancia", 1.8);
        prezzi.put("guava", 1.5);
        prezzi.put("mirtillo", 2.5);
        prezzi.put("banana", 1.0);

        System.out.printf(prezzi.toString()); // {arancia=1.8, banana=1.0, mela=2.0, mirtillo=2.5, guava=1.5}
    }
}</code></pre><p>Per creare una HashMap, devi prima importare la classe <code>java.util.HashMap</code> in cima al tuo file sorgente.</p><p>Poi, devi scrivere <code>HashMap</code> seguito dal tipo di dati della chiave e del valore all'interno di parentesi angolate e separati da una virgola.</p><p>In questo caso, le chiavi sono stringhe e i valori dei double. Dopo di ciò, aggiungi l'operatore di assegnazione seguito da <code>new HashMap&lt;&gt;()</code>.</p><p>Per inserire dei dati nell'HashMap puoi usare il metodo <code>put()</code>, che accetta la chiave come primo parametro e il valore corrispondente come secondo parametro.</p><p>Esiste anche il metodo <code>putIfAbsent()</code>, che aggiunge un determinato elemento solo se non è già presente nell'HashMap.</p><pre><code class="language-java">import java.util.HashMap;

public class Main {
    public static void main (String[] args) {
        HashMap&lt;String, Double&gt; prezzi = new HashMap&lt;&gt;();

        prezzi.put("mela", 2.0);
        prezzi.put("arancia", 1.8);
        prezzi.put("guava", 1.5);
        prezzi.put("mirtillo", 2.5);
        prezzi.put("banana", 1.0);

        prezzi.putIfAbsent("guava", 2.9);

        System.out.println(prezzi.toString()); // {arancia=1.8, banana=1.0, mela=2.0, mirtillo=2.5, guava=1.5}
    }
}</code></pre><p>Puoi usare il metodo <code>get()</code> per ottenere un valore da una HashMap. Il metodo prende la chiave come parametro.</p><pre><code class="language-java">import java.util.HashMap;

public class Main {
    public static void main (String[] args) {
        HashMap&lt;String, Double&gt; prezzi = new HashMap&lt;&gt;();

        prezzi.put("mela", 2.0);
        prezzi.put("arancia", 1.8);
        prezzi.put("guava", 1.5);
        prezzi.put("mirtillo", 2.5);
        prezzi.put("banana", 1.0);

        System.out.println(prezzi.get("banana")); // 1.000000
    }
}</code></pre><p>Esiste anche una variante di questo metodo. Il metodo <code>getOrDefault()</code> funziona come <code>get()</code> ma se la chiave data non viene trovata, restituisce un valore di default specificato.</p><pre><code class="language-java">import java.util.HashMap;

public class Main {
    public static void main (String[] args) {
        HashMap&lt;String, Double&gt; prezzi = new HashMap&lt;&gt;();

        prezzi.put("mela", 2.0);
        prezzi.put("arancia", 1.8);
        prezzi.put("guava", 1.5);
        prezzi.put("mirtillo", 2.5);
        prezzi.put("banana", 1.0);

        System.out.println(prezzi.getOrDefault("jackfruit", 0.0)); // 0.0
    }
}</code></pre><p>Il valore di default deve corrispondere al tipo di valori nell'HashMap. Puoi aggiornare un valore in una HashMap usando il metodo <code>replace()</code>:</p><pre><code class="language-java">import java.util.HashMap;

public class Main {
    public static void main (String[] args) {
        HashMap&lt;String, Double&gt; prezzi = new HashMap&lt;&gt;();

        prezzi.put("mela", 2.0);
        prezzi.put("arancia", 1.8);
        prezzi.put("guava", 1.5);
        prezzi.put("mirtillo", 2.5);
        prezzi.put("banana", 1.0);

        prezzi.replace("mirtillo", 2.8);

        System.out.printf(prezzi.toString()); // {arancia=1.8, banana=1.0, mela=2.0, mirtillo=2.8, guava=1.5}
    }
}</code></pre><p>Per rimuovere elementi da una HashMap, puoi usare il metodo <code>remove()</code>:</p><pre><code class="language-java">import java.util.HashMap;

public class Main {
    public static void main (String[] args) {
        HashMap&lt;String, Double&gt; prezzi = new HashMap&lt;&gt;();

        prezzi.put("mela", 2.0);
        prezzi.put("arancia", 1.8);
        prezzi.put("guava", 1.5);
        prezzi.put("mirtillo", 2.5);
        prezzi.put("banana", 1.0);

        prezzi.remove("guava");

        System.out.printf(prezzi.toString()); // {arancia=1.8, banana=1.0, mela=2.0, mirtillo=2.5}
    }
}</code></pre><p>Nel caso avessi bisogno di conoscere quanti dati sono presenti all'interno di una HashMap, puoi saperlo usando il metodo <code>size()</code>:</p><pre><code class="language-java">import java.util.HashMap;

public class Main {
    public static void main (String[] args) {
        HashMap&lt;String, Double&gt; prezzi = new HashMap&lt;&gt;();

        prezzi.put("mela", 2.0);
        prezzi.put("arancia", 1.8);
        prezzi.put("guava", 1.5);
        prezzi.put("mirtillo", 2.5);
        prezzi.put("banana", 1.0);

        System.out.println(prezzi.size()); // 5
    }
}</code></pre><p>Infine, se desideri svuotare una HashMap, puoi farlo grazie al metodo <code>clear()</code>.</p><pre><code class="language-java">import java.util.HashMap;

public class Main {
    public static void main (String[] args) {
        HashMap&lt;String, Double&gt; prices = new HashMap&lt;&gt;();

        prices.put("apple", 2.0);
        prices.put("orange", 1.8);
        prices.put("guava", 1.5);
        prices.put("berry", 2.5);
        prices.put("banana", 1.0);

        prices.clear();

        System.out.println(prices.toString()); // {}
    }
}</code></pre><p>Proprio come per gli ArrayList, il metodo non prende argomenti né restituisce valori.</p><h3 id="come-inserire-o-sostituire-elementi-multipli-in-una-hashmap"><strong>Come inserire o sostituire elementi multipli in una HashMap</strong></h3><p>Se vuoi inserire più elementi in una HashMap in un colpo solo, puoi farlo usando il metodo <code>putAll()</code>:</p><pre><code class="language-java">import java.util.HashMap;

public class Main {
    public static void main (String[] args) {
        HashMap&lt;String, Double&gt; prezzi = new HashMap&lt;&gt;();

        prezzi.put("mela", 2.0);
        prezzi.put("arancia", 1.8);
        prezzi.put("guava", 1.5);
        prezzi.put("mirtillo", 2.5);
        prezzi.put("banana", 1.0);

        HashMap&lt;String, Double&gt; altriPrezzi = new HashMap&lt;&gt;();

        altriPrezzi.put("jackfruit", 2.9);
        altriPrezzi.put("ananas", 1.1);
        altriPrezzi.put("pomodoro", 0.8);

        prezzi.putAll(altriPrezzi);

        System.out.println(prezzi.toString()); // {arancia=1.8, banana=1.0, mela=2.0, mirtillo=2.5, ananas=1.1, pomodoro=0.8, guava=1.5, jackfruit=2.9}
    }
}</code></pre><p>Il metodo prende un'altra HashMap come parametro e aggiunge i suoi elementi all'HashMap su cui è stato chiamato.</p><p>Puoi anche usare il metodo <code>replaceAll()</code> per aggiornare valori multipli in una HashMap.</p><pre><code class="language-java">import java.util.HashMap;

public class Main {
    public static void main (String[] args) {
        HashMap&lt;String, Double&gt; prezzi = new HashMap&lt;&gt;();

        prezzi.put("mela", 2.0);
        prezzi.put("arancia", 1.8);
        prezzi.put("guava", 1.5);
        prezzi.put("mirtillo", 2.5);
        prezzi.put("banana", 1.0);

        prezzi.replaceAll((frutto, prezzo) -&gt; prezzo * 2);

        System.out.println(prezzi.toString()); // {arancia=3.6, banana=2.0, mela=4.0, mirtillo=5.0, guava=3.0}
    }
}</code></pre><p>Il metodo <code>replaceAll()</code> itera sull'HashMap e passa ogni coppia chiave-valore all'espressione lambda.</p><p>Il primo parametro dell'espressione lambda è la chiave e il secondo è il valore. All'interno dell'espressione lambda puoi eseguire le azioni che desideri.</p><h3 id="come-verificare-se-una-hash-map-contiene-un-elemento-o-vuota"><strong>Come verificare se una Hash Map contiene un elemento o è vuota</strong></h3><p>Puoi usare i metodi <code>containsKey()</code> e <code>containsValue()</code> per controllare se una HashMap contiene un elemento oppure no.</p><pre><code class="language-java">import java.util.HashMap;

public class Main {
    public static void main (String[] args) {
        HashMap&lt;String, Double&gt; prezzi = new HashMap&lt;&gt;();

        prezzi.put("mela", 2.0);
        prezzi.put("arancia", 1.8);
        prezzi.put("guava", 1.5);
        prezzi.put("mirtillo", 2.5);
        prezzi.put("banana", 1.0);

        System.out.println(prezzi.containsKey("banana")); // true
        System.out.println(prezzi.containsValue(2.5)); // true
    }
}</code></pre><p>La differenza tra i due &nbsp;metodi è che il metodo <code>containsKey()</code> verifica se una data chiave è presente o meno, mentre il metodo <code>containsValue()</code> verifica se un dato valore è presente o meno.</p><p>Se vuoi sapere se una HashMap è vuota oppure no, puoi usare il metodo <code>isEmpty()</code>:</p><pre><code class="language-java">import java.util.HashMap;

public class Main {
    public static void main (String[] args) {
        HashMap&lt;String, Double&gt; prezzi = new HashMap&lt;&gt;();

        prezzi.put("mela", 2.0);
        prezzi.put("arancia", 1.8);
        prezzi.put("guava", 1.5);
        prezzi.put("mirtillo", 2.5);
        prezzi.put("banana", 1.0);

        System.out.println(prezzi.isEmpty()); // false
    }
}</code></pre><p>Dato che il metodo restituisce un valore booleano, puoi utilizzarlo in istruzioni <code>if</code>-<code>else</code>.</p><h3 id="come-eseguire-un-azione-su-tutti-gli-elementi-di-una-hashmap"><strong>Come eseguire un'azione su tutti gli elementi di una HashMap</strong></h3><p>Proprio come gli ArrayList, anche le HashMap possiedono un metodo <code>forEach()</code> che puoi usare per iterare sull'HashMap e ripetere determinate azioni su ogni dato.</p><pre><code class="language-java">import java.util.HashMap;

public class Main {
    public static void main (String[] args) {
        HashMap&lt;String, Double&gt; prezzi = new HashMap&lt;&gt;();

        prezzi.put("mela", 2.0);
        prezzi.put("arancia", 1.8);
        prezzi.put("guava", 1.5);
        prezzi.put("mirtillo", 2.5);
        prezzi.put("banana", 1.0);

        System.out.println("prezzi scontati");

        prices.forEach((frutto, prezzo) -&gt; {
            System.out.println(frutto + " - " + (prezzo - 0.5));
        });
    }
}

// prezzi scontati
// arancia - 1.3
// banana - 0.5
// mela - 1.5
// mirtillo - 2.0
// guava - 1.0</code></pre><p>Il metodo itera su ogni dato e passa la chiave e il valore all'espressione lambda. All'interno del corpo dell'espressioni lambda, puoi fare ciò che desideri.</p><h2 id="classi-e-oggetti-in-java"><strong>Classi e Oggetti in Java</strong></h2><p>Ecco un'utile definizione di <a href="https://en.wikipedia.org/wiki/Object-oriented_programming">programmazione orientata agli oggetti</a>:</p><blockquote>La programmazione orientata agli oggetti (OOP, Object-oriented programming) è un paradigma di programmazione basato sul concetto di "oggetti", che possono contenere dati e codice: dati in forma di campi (spesso chiamati attributi o proprietà) e codice in forma di procedure (spesso chiamate metodi).</blockquote><p>Immagina il sistema di gestione di una libreria, dove i membri della libreria possono accedere e vedere i libri che hanno già preso in prestito, richiederne nuovi e così via.</p><p>In questo sistema, gli utenti e i libri possono essere tutti oggetti. Questi oggetti avranno le loro proprietà come nome e data di nascita, nel caso di un utente, e titolo e autore, nel caso dei libri.</p><p>Le classi nella programmazione orientata agli oggetti sono i modelli per gli oggetti precedentemente menzionati. Abbiamo già parlato delle possibili proprietà degli oggetti utente e libro.</p><p>Per creare una nuova classe <code>Utente</code>, clicca ancora con il tasto destro sulla cartella <code>src</code>. Poi vai su <strong><strong>New &gt; Java Class</strong></strong>, chiamala <code>Utente</code> e premi invio.</p><p>Tenendo a mente le proprietà discusse in precedenza, il codice della classe <code>Utente</code> dovrebbe essere come segue:</p><pre><code class="language-java">import java.time.LocalDate;

public class Utente {
    String nome;
    LocalDate dataDiNascita;
}</code></pre><p><code>LocalDate</code> è un tipo di dato riferimento che rappresenta una data. Ora torna al file <code>Main.java</code> e crea una nuova istanza di questa classe:</p><pre><code class="language-java">import java.time.LocalDate;

public class Main {
    public static void main (String[] args) {
        Utente utente = new Utente();

        utente.nome = "Farhan";
        utente.dataDiNascita = LocalDate.parse("1996-07-15");

        System.out.printf("%s è nato il %s.", utente.nome, utente.dataDiNascita.toString()); // Farhan è nato il 1996-07-15.
    }
}

</code></pre><p>Creare un nuovo utente non è molto diverso da creare una nuova stringa o un array. Inizi scrivendo il nome della classe, poi il nome dell'istanza o dell'oggetto.</p><p>Aggiungi l'operatore di assegnazione seguito dalla parola chiave <code>new</code> e dalla chiamata del costruttore. Il costruttore è un metodo speciale che inizializza l'oggetto.</p><p>Il costruttore inizializza le proprietà dell'oggetto con dei valori predefiniti, e cioè <code>null</code> per tutti i tipi riferimento.</p><p>Puoi accedere alle proprietà di un oggetto scrivendo il nome dell'oggetto seguito da un punto e dal nome della proprietà.</p><p>Il metodo <code>LocalDate.parse()</code> interpreta la data dalla stringa specificata. Dato che <code>dataDiNascita</code> è un riferimento, occorre usare il metodo <code>toString()</code> per stamparla sulla console.</p><h3 id="cos-un-metodo"><strong>Cos'è un metodo?</strong></h3><p>Le variabili o le proprietà di una classe descrivono lo stato dei suoi oggetti. I metodi invece, ne descrivono il comportamento.</p><p>Ad esempio, nella classe <code>Utente</code> possiamo avere un metodo che calcola l'età dell'utente.</p><pre><code class="language-java">import java.time.Period;
import java.time.LocalDate;

public class Utente {
    String nome;
    LocalDate dataDiNascita;

    int eta() {
        return Period.between(this.dataDiNascita, LocalDate.now()).getYears();
    }
}</code></pre><p>Qui, la parola chiave <code>this</code> rappresenta l'istanza attuale della classe. Iniziamo scrivendo il tipo del valore di ritorno del metodo. Dato che l'età di un utente è un intero, il valore restituito da questo metodo sarà di tipo <code>int</code>.</p><p>Poi scriviamo il nome del metodo, seguito dalle parentesi.</p><p>È il momento di scrivere il corpo del metodo, all'interno di parentesi graffe. La classe <code>Period</code> in Java esprime un periodo di tempo secondo il sistema del calendario ISO-8601. Il metodo <code>LocalDate.now()</code> restituisce la data corrente.</p><p>Quindi la chiamata <code>Period.between(this.dataDiNascita, LocalDate.now()).getYears()</code> restituisce la differenza tra la data corrente e la data di nascita in anni.</p><p>Ora torniamo al file <code>Main.java</code> file e chiamiamo il metodo come segue:</p><pre><code class="language-java">import java.time.LocalDate;

public class Main {
    public static void main (String[] args) {
        Utente utente = new Utente();

        utente.nome = "Farhan";
        utente.dataDiNascita = LocalDate.parse( "1996-07-15");

        System.out.printf("%s ha %s anni.", utente.nome, utente.eta()); // Farhan ha 26 anni.
    }
}

</code></pre><p>I metodi possono anche accettare dei parametri. Ad esempio, se vuoi creare un metodo <code>prestito()</code> per inserire nuovi libri nella lista dei libri presi in prestito da un utente, puoi farlo in questo modo:</p><pre><code class="language-java">import java.time.LocalDate;
import java.time.Period;
import java.util.ArrayList;

public class Utente {
    String nome;
    LocalDate dataDiNascita;
    
    ArrayList&lt;String&gt; libriPresiInPrestito = new ArrayList&lt;String&gt;();

    int eta() {
        return Period.between(this.dataDiNascita, LocalDate.now()).getYears();
    }

    void prestito(String titoloLibro) {
        this.libriPresiInPrestito.add(titoloLibro);
    }
}</code></pre><p>Tornando al file <code>Main.java</code>, possiamo chiamare il metodo in questo modo:</p><pre><code class="language-java">public class Main {
    public static void main (String[] args) {
        Utente utente = new Utente();

        utente.nome = "Farhan";

        utente.prestito("Carmilla");
        utente.prestito("Hard West");

        System.out.printf("%s ha preso in prestito questi libri: %s", utente.nome, utente.libriPresiInPrestito.toString()); // Farhan ha preso in prestito questi libri: [Carmilla, Hard West]
    }
}

</code></pre><p>Allo stesso modo, creiamo una classe per i libri:</p><pre><code class="language-java">import java.util.ArrayList;

public class Libro {
    String titolo;
    ArrayList&lt;String&gt; autori = new ArrayList&lt;String&gt;();
}
</code></pre><p>Spesso i libri hanno più di un autore. Adesso creiamo una nuova istanza di <code>Libro</code> nel file <code>Main.java</code>.</p><pre><code class="language-java">import java.time.LocalDate;

public class Main {
    public static void main (String[] args){
        Utente utente = new Utente();
        utente.nome = "Farhan";
        utente.dataDiNascita = LocalDate.parse("1996-07-15");

        Libro libro = new Libro();
        libro.titolo = "Carmilla";
        libro.autori.add("Sheridan Le Fanu");

        System.out.printf("%s è stato scritto da %s", libro.titolo, libro.autori.toString()); // Carmilla è stato scritto da [Sheridan Le Fanu]
    }
}</code></pre><p>Ora torniamo al file <code>Utente.java</code> e creiamo una relazione tra gli utenti e i libri:</p><pre><code class="language-java">import java.time.LocalDate;
import java.time.Period;
import java.util.ArrayList;

public class Utente {
    String nome;
    LocalDate dataDiNascita;

    ArrayList&lt;Libro&gt; libriPresiInPrestito = new ArrayList&lt;Libro&gt;();

    int eta() {
        return Period.between(this.dataDiNascita, LocalDate.now()).getYears();
    }

    void prestito(Libro libro) {
        this.libriPresiInPrestito.add(libro);
    }
}</code></pre><p>Invece di usare un ArrayList di stringhe, adesso stiamo usando un ArrayList di libri per conservare i libri presi in prestito da un utente.</p><p>Dato che il tipo dell'argomento del metodo è cambiato, di conseguenza dovrai aggiornare il codice nel file <code>Main.java</code>:</p><pre><code class="language-java">import java.time.LocalDate;

public class Main {
    public static void main (String[] args){
        Utente utente = new Utente();
        utente.nome = "Farhan";
        utente.dataDiNascita = LocalDate.parse("1996-07-15");

        Libro libro = new Libro();
        libro.titolo = "Carmilla";
        libro.autori.add("Sheridan Le Fanu");

        utente.prestito(libro);

        System.out.printf("%s ha preso in prestito questi libri: %s", utente.nome, utente.libriPresiInPrestito.toString()); // Farhan ha preso in prestito questi libri: [Libro@30dae81]
    }</code></pre><p>Tutto funziona a dovere, eccetto il fatto che le informazioni sui libri non vengono stampate in modo appropriato.</p><p>Spero che ti ricordi del metodo <code>toString()</code>. Quando chiamiamo <code>utente.libriPresiInPrestito.toString()</code> il compilatore realizza che gli elementi contenuti nell'ArrayList &nbsp;sono oggetti o riferimenti. Quindi inizia a chiamare il metodo <code>toString()</code> in questi elementi.</p><p>Il problema è che non esiste un'implementazione appropriata di <code>toString()</code> nella classe <code>Libro</code>. Apri <code>Libro.java</code> e aggiorna il suo codice come segue:</p><pre><code class="language-java">import java.util.ArrayList;

public class Libro {
    String titolo;
    ArrayList&lt;String&gt; autori = new ArrayList&lt;String&gt;();

    public String toString() {
        return String.format("%s di %s", this.titolo, this.autori.toString());
    }
}
</code></pre><p>Adesso, il metodo <code>toString()</code> restituisce una stringa ben formattata invece del riferimento all'oggetto. Esegui ancora il codice e questa volta l'output dovrebbe essere <code>Farhan ha preso in prestito questi libri: [Carmilla di [Sheridan Le Fanu]]</code>.</p><p>Come puoi vedere, essere in grado di progettare il tuo software con delle entità reali lo rende molto più comprensibile. Anche se è tutto incentrato su un ArrayList e qualche stringa, è come se l'operazione di prestito del libro avvenga davvero.</p><h3 id="cos-l-overloading-dei-metodi"><strong>Cos'è l'overloading dei metodi?</strong></h3><p>In Java, più metodi possono avere lo stesso nome se i loro parametro sono diversi. Ciò viene detto overloading dei metodi.</p><p>Un esempio può essere il metodo <code>prestito()</code> nella classe <code>Utente()</code>. Adesso accetta un singolo libro come parametro. Creiamo una versione di overload che invece accetta un array di libri.</p><pre><code class="language-java">import java.time.LocalDate;
import java.time.Period;
import java.util.ArrayList;
import java.util.Arrays;

public class Utente {
    private String nome;
    private LocalDate dataDiNascita;

    private ArrayList&lt;Libro&gt; libriPresiInPrestito = new ArrayList&lt;Libro&gt;();

    public String getNome() {
        return this.nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getLibriPresiInPrestito() {
        return this.libriPresiInPrestito.toString();
    }

    Utente (String nome, String dataDiNascita) {
        this.nome = nome;
        this.dataDiNascita = LocalDate.parse(dataDiNascita);
    }

    int eta() {
        return Period.between(this.dataDiNascita, LocalDate.now()).getYears();
    }

    void prestito(Libro libro) {
        this.libriPresiInPrestito.add(libro);
    }

    void prestito(Libro[] libri) {
        libriPresiInPrestito.addAll(Arrays.asList(libri));
    }
}
</code></pre><p>Il tipo del valore di ritorno del nuovo metodo è identico al precedente, ma questo accetta un array di oggetti <code>Libro</code> invece di un singolo oggetto.</p><p>Aggiorniamo il file <code>Main.java</code> per poter usare questo metodo di overload.</p><pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        Utente utente = new Utente("Farhan", "1996-07-15");

        Libro libro1 = new Libro("Carmilla", new String[]{"Sheridan Le Fanu"});
        Libro libro2 = new Libro("Frankenstein", new String[]{"Mary Shelley"});
        Libro libro3 = new Libro("Dracula", new String[]{"Bram Stoker"});

        utente.prestito(new Libro[]{libro1, libro2});

        utente.prestito(libro3);

        System.out.printf("%s ha preso in prestito questi libri: %s", utente.getNome(), utente.getLibriPresiInPrestito());
    }
}</code></pre><p>Come puoi vedere, adesso il metodo <code>prestito()</code> accetta un array di libri o un singolo oggetto libro senza problemi.</p><h2 id="cosa-sono-i-costruttori-in-java"><strong>Cosa sono i costruttori in Java?</strong></h2><p>Un costruttore è un tipo particolare di metodo presente in ogni classe e che viene chiamato dal compilatore ogni volta che crei un nuovo oggetto da una classe. </p><p>Dato che il metodo è chiamato durante la costruzione di un oggetto, prende il nome di costruttore. Di default, un costruttore assegna dei valori predefiniti a tutte le sue proprietà.</p><p>Per sovrascrivere il costruttore predefinito, devi creare un nuovo metodo in una classe con lo stesso nome della classe.</p><pre><code class="language-java">import java.time.LocalDate;
import java.time.Period;
import java.util.ArrayList;

public class Utente {
    public String nome;
    public LocalDate dataDiNascita;
    public ArrayList&lt;Libro&gt; libriPresiInPrestito = new ArrayList&lt;Libro&gt;();

    Utente (String nome, String dataDiNascita) {
        this.nome = nome;
        this.dataDiNascita = LocalDate.parse(dataDiNascita);
    }

    int eta() {
        return Period.between(this.dataDiNascita, LocalDate.now()).getYears();
    }

    void prestito(Libro libro) {
        this.libriPresiInPrestito.add(libro);
    }
}</code></pre><p>Ora che abbiamo il costruttore, invece di prendere la data da una stringa nel file <code>Main.java</code>, possiamo farlo qui.</p><p>Questo perché il formato della data di nascita interessa la classe <code>Utente</code> e la classe <code>Main</code> non ha bisogno di preoccuparsene.</p><p>Stesso trattamento per la classe <code>Libro</code>:</p><pre><code class="language-java">import java.util.ArrayList;
import java.util.Arrays;

public class Libro {
    public String titolo;
    public ArrayList&lt;String&gt; autori = new ArrayList&lt;String&gt;();

    Libro(String titolo, String[] autori) {
        this.titolo = titolo;
        this.autori = new ArrayList&lt;String&gt;(Arrays.asList(autori));
    }

    public String toString() {
        return String.format("%s di %s", this.titolo, this.autori.toString());
    }
}</code></pre><p>Di nuovo, il tipo della collezione <code>autori</code> non è una preoccupazione della classe <code>Main</code>. Il modo più semplice per lavorare con un gruppo di valori in Java è usare un array.</p><p>Quindi, otteniamo i nomi degli autori come un array dalla classe <code>Main</code> e da esso creiamo un ArrayList nella classe <code>Libro</code>.</p><p>Ora dobbiamo passare questi parametri al costruttore quando creiamo un nuovo oggetto utente o libro nel file <code>Main.java</code>.</p><pre><code class="language-java">import java.util.ArrayList;

public class Main {
    public static void main (String[] args) {
        Utente utente = new Utente("Farhan", "1996-07-15");

        Libro libro = new Libro("Carmilla", new String[]{"Sheridan Le Fanu"});

        utente.prestito(libro);

        System.out.printf("%s ha preso in prestito questi libri: %s", utente.nome, utente.libriPresiInPrestito.toString()); // Farhan ha preso in prestito questi libri: [Carmilla, Hard West]
    }
}</code></pre><p>Guarda come sembra già tutto più pulito, e presto sarà ancora meglio.</p><h2 id="cosa-sono-i-modificatori-di-accesso-in-java"><strong>Cosa sono i modificatori di accesso in Java?</strong></h2><p>Hai già visto più volte la parola chiave <code>public</code>. Si tratta di uno dei modificatori di accesso di Java.</p><p>Esistono quattro modificatori di accesso in Java:</p><!--kg-card-begin: markdown--><table>
<thead>
<tr>
<th>Modificatore di accesso</th>
<th>Descrizione</th>
</tr>
</thead>
<tbody>
<tr>
<td>default</td>
<td>Accessibile nel pacchetto</td>
</tr>
<tr>
<td>public</td>
<td>Accessibile ovunque</td>
</tr>
<tr>
<td>private</td>
<td>Accessibile nella classe</td>
</tr>
<tr>
<td>protected</td>
<td>Accessibile nella classe e nelle sottoclassi</td>
</tr>
</tbody>
</table>
<!--kg-card-end: markdown--><p>Per ora, parleremo dei modificatori di accesso <code>default</code>, <code>public</code> e <code>private</code>. <code>protected</code> sarà discusso in una sezione successiva.</p><p>Hai già imparato cosa sono le classi. I pacchetti sono collezioni di più classi separate secondo le loro funzionalità.</p><p>Ad esempio, se stai creando un gioco, puoi mettere tutte le classi relative alla fisica in un pacchetto e quelle relative alla grafica in un altro pacchetto.</p><p>I pacchetti vanno oltre lo scopo di questo manuale, ma man mano che continui a lavorare su progetti più grandi ci prenderai la mano.</p><p>Il modificatore di accesso <code>public</code> è abbastanza autoesplicativo. Variabili, metodi o classi <code>public</code> sono accessibili da ogni altra classe o pacchetto nel tuo progetto.</p><p>Quelli <code>private</code>, d'altro canto, sono disponibili soltanto nella loro classe.</p><p>Prendiamo come esempio la classe <code>Utente</code>. Il nome e la data di nascita di un utente non dovrebbero essere accessibili dall'esterno.</p><pre><code class="language-java">import java.time.LocalDate;
import java.time.Period;
import java.util.ArrayList;

public class Utente {
    private String nome;
    private LocalDate dataDiNascita;
    private ArrayList&lt;Libro&gt; libriPresiInPrestito = new ArrayList&lt;Libro&gt;();

    Utente (String nome, String dataDiNascita) {
        this.nome = nome;
        this.dataDiNascita = LocalDate.parse(dataDiNascita);
    }

    int eta() {
        return Period.between(this.dataDiNascita, LocalDate.now()).getYears();
    }

    void prestito(Libro libro) {
        this.libriPresiInPrestito.add(libro);
    }
}</code></pre><p>Così va meglio. Aggiorniamo anche la classe <code>Libro</code> per rendere le informazioni relative a titolo e autore nascoste dall'esterno.</p><pre><code class="language-java">import java.util.ArrayList;
import java.util.Arrays;

public class Libro {
    private String titolo;
    private ArrayList&lt;String&gt; autori = new ArrayList&lt;String&gt;();

    Libro(String titolo, String[] autori) {
        this.titolo = titolo;
        this.autori = new ArrayList&lt;String&gt;(Arrays.asList(autori));
    }

    public String toString() {
        return String.format("%s di %s", this.titolo, this.autori.toString());
    }
}
</code></pre><p>Visto che le proprietà ora sono private, la riga <code>System.out.println()</code> nel file <code>Main.java</code> fallirà nell'accedervi direttamente e otterremo un errore.</p><p>La soluzione a questo problema è scrivere metodi pubblici che le altre classi possono usare per accedere a queste proprietà.</p><h2 id="cosa-sono-i-metodi-getter-e-setter-in-java"><strong>Cosa sono i metodi getter e setter in Java?</strong></h2><p>Getter e setter sono metodi pubblici usati per leggere e scrivere delle proprietà private.</p><pre><code class="language-java">import java.time.LocalDate;
import java.time.Period;
import java.util.ArrayList;
import java.util.Arrays;

public class Utente {
    private String nome;
    private LocalDate dataDiNascita;
    private ArrayList&lt;Libro&gt; libriPresiInPrestito = new ArrayList&lt;Libro&gt;();

    public String getNome() {
        return this.nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getLibriPresiInPrestito() {
        return this.libriPresiInPrestito.toString();
    }

    Utente (String nome, String dataDiNascita) {
        this.nome = nome;
        this.dataDiNascita = LocalDate.parse(dataDiNascita);
    }

    int eta() {
        return Period.between(this.dataDiNascita, LocalDate.now()).getYears();
    }

    void prestito(Libro libro) {
        this.libriPresiInPrestito.add(libro);
    }
}
</code></pre><p>I metodi <code>getNome()</code> e <code>getLibriPresiInPrestito()</code> sono responsabili di restituire il valore delle variabili <code>nome</code> e <code>libriPresiInPrestito</code>.</p><p>Non accediamo mai alla varabile <code>dataDiNascita</code> al di fuori dal metodo <code>eta()</code>, quindi un getter non è necessario.</p><p>Dato che il tipo della variabile <code>libriPresiInPrestito</code> non riguarda la classe <code>Main</code>, il getter ci assicura di restituire il valore nel formato appropriato.</p><p>Adesso aggiorniamo il codice nel file <code>Main.java</code> in modo che usi questi metodi:</p><pre><code class="language-java">public class Main {
    public static void main (String[] args) {
        Utente utente = new Utente("Farhan", "1996-07-15");

        Libro libro = new Libro("Carmilla", new String[]{"Sheridan Le Fanu"});

        utente.prestito(libro);

        System.out.printf("%s ha preso in prestito questi libri: %s", utente.getNome(), utente.getLibriPresiInPrestito());
    }
}</code></pre><p>Ottimo. Ora il codice è addirittura più pulito e facile da leggere. Analogamente ai getter, i setter vengono usati per scrivere i valori di proprietà private.</p><p>Ad esempio, potresti desiderare di permettere all'utente di cambiare la sua data di nascita. Il metodo <code>prestito()</code> funziona già come un setter per l'ArrayList <code>libriPresiInPrestito</code>.</p><pre><code class="language-java">import java.time.LocalDate;
import java.time.Period;
import java.util.ArrayList;
import java.util.Arrays;

public class Utente {
    private String nome;
    private LocalDate dataDiNascita;
    private ArrayList&lt;Libro&gt; libriPresiInPrestito = new ArrayList&lt;Libro&gt;();

    public String getNome() {
        return this.nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public void setDataDiNascita(String dataDiNascita) {
        this.dataDiNascita = LocalDate.parse(dataDiNascita);
    }
    
    public String getLibriPresiInPrestito() {
        return this.libriPresiInPrestito.toString();
    }

    Utente (String nome, String dataDiNascita) {
        this.nome = nome;
        this.dataDiNascita = LocalDate.parse(dataDiNascita);
    }

    int eta() {
        return Period.between(this.dataDiNascita, LocalDate.now()).getYears();
    }

    void prestito(Libro libro) {
        this.libriPresiInPrestito.add(libro);
    }
}
</code></pre><p>Ora possiamo chiamare il metodo <code>setNome()</code> con qualsiasi nome vogliamo impostare all'utente. Analogamente, possiamo usare <code>setDataDiNascita()</code> per impostare la data di nascita.</p><p>Implementiamo dei getter e dei setter anche nella classe <code>Libro</code>.</p><pre><code class="language-java">import java.util.ArrayList;
import java.util.Arrays;

public class Libro {
    private String titolo;
    private ArrayList&lt;String&gt; autori = new ArrayList&lt;String&gt;();

    public String getTitolo() {
        return this.titolo;
    }

    public void setTitolo(String titolo) {
        this.titolo = titolo;
    }

    public String getAutori() {
        return this.autori.toString();
    }

    public void setAutori(String[] autori) {
        this.autori = new ArrayList&lt;String&gt;(Arrays.asList(autori));
    }
    
    Libro(String titolo, String[] autori) {
        this.titolo = titolo;
        this.autori = new ArrayList&lt;String&gt;(Arrays.asList(autori));
    }

    public String toString() {
        return String.format("%s di %s", this.titolo, this.autori.toString());
    }
}</code></pre><p>Ora non puoi accedere direttamente a queste proprietà, ma devi utilizzare i getter e setter appropriati.</p><h2 id="cos-l-ereditariet-in-java"><strong>Cos'è l'ereditarietà in Java?</strong></h2><p>L'ereditarietà è un'altra importante caratteristica della programmazione orientata agli oggetti. Immagina di avere tre tipi di libri. Quelli normali, gli e-book e gli audiolibri.</p><p>Anche se hanno delle somiglianze, visto che hanno un titolo e un autore, hanno anche alcune differenze. Ad esempio, i libri normali e gli e-book hanno delle pagine mentre gli audiolibri hanno un tempo di esecuzione. Gli e-book possono essere in formato PDF e EPUB.</p><p>Quindi usare la stessa classe per tutti e tre non è un'opzione, ma questo non vuol dire che dobbiamo creare tre classi separate con piccole differenze. Possiamo creare classi separate per e-book e audiolibri e far ereditare loro le proprietà e i metodi della classe <code>Libro</code>.</p><p>Iniziamo aggiungendo il numero delle pagine alla classe <code>Libro</code>:</p><pre><code class="language-java">import java.util.ArrayList;
import java.util.Arrays;

public class Libro {
    private String titolo;
    private int pagine;
    private ArrayList&lt;String&gt; autori = new ArrayList&lt;String&gt;();

    Libro(String titolo, int pagine, String[] autori) {
        this.titolo = titolo;
        this.pagine = pagine;
        this.autori = new ArrayList&lt;String&gt;(Arrays.asList(autori));
    }

    public String length() {
        return String.format("%s ha %d pagine.", this.titolo, this.pagine);
    }

    public String toString() {
        return String.format("%s di %s", this.titolo, this.autori.toString());
    }
}</code></pre><p>Visto che non useremo getter e setter in questi esempi, mi è sembrata una buona idea fare un po' di pulizia. Il metodo <code>length()</code> restituisce la lunghezza del libro come una stringa.</p><p>Ora creiamo una nuova classe Java chiamata <code>AudioLibro</code> con il seguente codice:</p><pre><code class="language-java">public class AudioLibro extends Libro{
    private int durata;

    AudioLibro(String titolo, String[] autori, int durata) {
        super(titolo, 0, autori);

        this.durata = durata;
    }
}</code></pre><p>La parola chiave <code>extends</code> fa sapere al compilatore che questa classe è una sottoclasse della classe <code>Libro</code>. Ciò significa che questa classe eredita tutte le proprietà e i metodi della classe genitore.</p><p>All'interno del metodo costruttore <code>AudioLibro</code>, impostiamo la durata dell'audiolibro – ma occorre anche chiamare manualmente il costruttore della classe genitore.</p><p>La parola chiave <code>super</code> in Java fa riferimento alla classe genitore, quindi <code>super(titolo, 0, autori)</code> chiama essenzialmente il metodo costruttore genitore con i parametri necessari.</p><p>Visto che gli audiolibri non hanno pagine, impostare il numero di pagine a zero può essere una buona soluzione.</p><p>Oppure possiamo creare una versione di overload del metodo costruttore <code>Libro</code> che non richiede il numero di pagine.</p><p>Come prossimo passo, creiamo un'altra classe Java chiamata <code>Ebook</code> con il seguente codice:</p><pre><code class="language-java">public class Ebook extends Libro{
    private String formato;

    Ebook(String titolo, int pagine, String[] autori, String formato) {
        super(titolo, pagine, autori);

        this.formato = formato;
    }
}</code></pre><p>Questa classe è praticamente identica alla classe <code>Libro</code> eccetto per il fatto che possiede una proprietà <code>formato</code>.</p><pre><code class="language-java">public class Main {
    public static void main (String[] args) {
        Libro libro = new Libro("Carmilla", 200, new String[]{"Sheridan Le Fanu"});
        Ebook ebook = new Ebook("Frankenstein", 220, new String[]{"Mary Shelley"}, "EPUB");
        AudioLibro audioLibro = new AudioLibro("Dracula", new String[]{"Bram Stoker"}, 160);

        System.out.println(libro.toString()); // Carmilla di [Sheridan Le Fanu]
        System.out.println(ebook.toString()); // Frankenstein di [Mary Shelley]
        System.out.println(audioLibro.toString()); // Dracula di [Bram Stoker]
    }
}</code></pre><p>Per ora va tutto bene. Ma ricordi il metodo <code>length()</code> che abbiamo scritto nella classe <code>Libro</code>? Funzionerà per i libri ma non per gli e-book.</p><p>Questo perché la proprietà <code>pagine</code> è <code>private</code> e nessuna altra classe eccetto <code>Libro</code> può accedervi. Anche il <code>titolo</code> è una proprietà <code>private</code>.</p><p>Apriamo il file <code>Book.java</code> e segniamo le proprietà <code>titolo</code> e <code>pagine</code> come <code>protected</code>.</p><pre><code class="language-java">import java.util.ArrayList;
import java.util.Arrays;

public class Libro {
    protected String titolo;
    protected int pagine;
    private ArrayList&lt;String&gt; autori = new ArrayList&lt;String&gt;();

    Libro(String titolo, int pagine, String[] autori) {
        this.titolo = titolo;
        this.pagine = pagine;
        this.autori = new ArrayList&lt;String&gt;(Arrays.asList(autori));
    }

    public String length() {
        return String.format("%s ha %d pagine.", this.titolo, this.pagine);
    }

    public String toString() {
        return String.format("%s di %s", this.titolo, this.autori.toString());
    }
}</code></pre><p>In questo modo saranno accessibili dalle sottoclassi. Gli audiolibri hanno un altro problema con il metodo <code>length()</code>.</p><p>Gli audiolibri non hanno pagine, ma hanno una durata e questa differenza non farà funzionare il metodo <code>length()</code>.</p><p>Un modo per risolvere questo problema è sovrascrivere il metodo.</p><h2 id="come-sovrascrivere-un-metodo-in-java"><strong>Come sovrascrivere un metodo in Java</strong></h2><p>Come suggerisce il nome, sovrascrivere vuol dire cancellare gli effetti di un metodo sostituendolo con qualcos'altro.</p><pre><code class="language-java">public class AudioLibro extends Libro{
    private int durata;

    AudioLibro(String titolo, String[] autori, int durata) {
        super(titolo, 0, autori);

        this.durata = durata;
    }
    
    @Override
    public String length() {
        return String.format("%s dura %d minuti.", this.titolo, this.durata);
    }
}</code></pre><p>Sovrascriviamo un metodo della classe genitore riscrivendolo nella sottoclasse. La parola chiave <code>@Override</code> è un'annotazione. In Java, le annotazioni sono metadati.</p><p>Non è obbligatorio annotare il metodo in questo modo, ma se lo fai il compilatore saprà che il metodo annotato sovrascrive un metodo genitore e farà in modo che vengano seguite tutte le regole di sovrascrittura.</p><p>Ad esempio, se fai un errore nel nome del metodo, così che non corrisponda più a nessun metodo del genitore, il compilatore ti farà sapere che il metodo non sta sovrascrivendo nulla.</p><pre><code class="language-java">public class Main {
    public static void main (String[] args) {
        AudioLibro audioLibro = new AudioLibro("Dracula", new String[]{"Bram Stoker"}, 160);

        System.out.println(audioLibro.length()); // Dracula dura 160 minuti.
    }
}</code></pre><p>Fantastico, non è vero? Ogni volta che sovrascrivi un metodo in Java, tieni a mente che sia il metodo originale che quello che lo sovrascrive devono avere lo stesso tipo di valore di ritorno, stesso nome e stessi parametri.</p><h2 id="conclusione"><strong>Conclusione</strong></h2><p>Ti ringrazio di cuore per aver speso il tuo tempo leggendo questo manuale. Spero che tu ti sia divertito e che tu abbia imparato i concetti fondamentali di Java.</p><p>Questo manuale non è congelato nel tempo. Continuerò a lavorarci su e aggiornarlo con miglioramenti, nuovi contenuti e altro. Puoi darmi opinioni e suggerimenti sul manuale in forma anonima con <a href="https://forms.gle/RYPzQybBEYNc5q9g9">questo form</a>.</p><p>Oltre a questo, ho scritto altri manuali completi su altri argomenti complicati che sono disponibili gratuitamente su <a href="https://www.freecodecamp.org/news/author/farhanhasin/">freeCodeCamp</a>.</p><p>Questi manuali sono parte della mia missione di semplificare per tutti l'apprendimento di tecnologie difficili da comprendere. La stesura di ognuno di questi manuali richiede molto tempo e impegno.</p><p>Se ti è piaciuto leggere questo manuale e vuoi motivarmi, considera di lasciarmi delle stelle su <a href="https://github.com/fhsinchy/">GitHub</a> e sostienimi per le mie competenze su <a href="https://www.linkedin.com/in/farhanhasin/">LinkedIn</a>.</p><p>Sono sempre aperto a suggerimenti e discussioni su <a href="https://twitter.com/frhnhsin">Twitter</a> o <a href="https://www.linkedin.com/in/farhanhasin/">LinkedIn</a>. Contattami con un messaggio privato.</p><p>Infine, considera di condividere queste risorse con altri, perché:</p><blockquote>Nell'open source, sentiamo fortemente che per fare ben qualcosa, devi coinvolgere tante persone. — Linus Torvalds</blockquote><p>Buono studio, ci vediamo alla prossima.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Come usare Arrays.binarySearch() in Java ]]>
                </title>
                <description>
                    <![CDATA[ In questo articolo, ti mostrerò come utilizzare il metodo Arrays.binarySearch()  in Java. Cos'è Arrays.binarySearch() in Java? Secondo la documentazione ufficiale [https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#binarySearch(byte[],%20byte)]  sul metodo Arrays.binarySearch(): > Ricerca nell'array di byte specificato il valore indicato usando l'algoritmo di ricerca binaria. L'array deve essere ordinato (ad esempio con il metodo sort(byte[]) ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/come-usare-arrays-binarysearch-in-java/</link>
                <guid isPermaLink="false">63334a29f289f30743396cb3</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Dario Di Cillo ]]>
                </dc:creator>
                <pubDate>Thu, 06 Oct 2022 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2022/09/Arrays.binarySearch---in-Java.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/how-to-use-arrays-binarysearch-in-java/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Use Arrays.binarySearch() in Java</a>
      </p><p>In questo articolo, ti mostrerò come utilizzare il metodo <code>Arrays.binarySearch()</code> in Java.</p><h2 id="cos-arrays-binarysearch-in-java"><strong>Cos'è <code>Arrays.binarySearch()</code> in Java?</strong></h2><p>Secondo la <a href="https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#binarySearch(byte[],%20byte)">documentazione ufficiale</a> sul metodo <code>Arrays.binarySearch()</code>:</p><blockquote>Ricerca nell'array di byte specificato il valore indicato usando l'algoritmo di ricerca binaria.<br><br>L'array deve essere ordinato (ad esempio con il metodo <a href="https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#sort(byte[])"><code>sort(byte[])</code></a>) prima della chiamata. Se non è ordinato, il risultato non è definito.<br><br>Se l'array contiene più elementi con il valore specificato, non è garantito quale di essi sarà trovato.</blockquote><p>In parole povere, il metodo <code>Arrays.binarySearch()</code> può cercare un dato elemento in un array ordinato e restituire il suo indice se la ricerca ha successo.</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {
		char vocali[] = {'a', 'e', 'i', 'o', 'u'};
		
		char chiave = 'i';
		
		int trovaIndiceElemento = Arrays.binarySearch(vocali, chiave);
		
		System.out.println("La vocale indicata ha indice: " + trovaIndiceElemento);

	}
}
</code></pre><p>Il metodo <code>Arrays.binarySearch()</code> prende come primo argomento l'array su cui effettuare la ricerca e la chiave di ricerca come secondo argomento. L'output di questo programma sarà:</p><pre><code>La vocale indicata ha indice: 2</code></pre><p>Ricorda, il metodo restituisce l'indice dell'elemento trovato e non l'elemento stesso. Quindi puoi conservare l'indice in un intero come quello usato in questo esempio.</p><p>Come impostazione predefinita, il metodo usa il primo indice dell'array come punto di partenza della ricerca e la lunghezza dell'array come termine. Quindi in questo caso l'indice di partenza è <code>0</code> e quello di fine è <code>6</code>.</p><p>Invece di usare gli indici predefiniti, puoi definirli tu stesso. Ad esempio, se vuoi svolgere la ricerca dall'indice <code>2</code> all'indice <code>4</code>, puoi farlo in questo modo:</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {
		char vocali[] = {'a', 'e', 'i', 'o', 'u'};
		
		char chiave = 'i';
		int indicePartenza = 2;
		int indiceFine = 4;
		
		int trovaIndiceElemento = Arrays.binarySearch(vocali, indicePartenza, indiceFine, chiave);
		
		System.out.println("La vocale indicata ha indice: " + trovaIndiceElemento);

	}
}
</code></pre><p>In questo caso, il metodo <code>Arrays.binarySearch()</code> prende l'array su cui vuoi effettuare la ricerca come primo argomento, l'indice di partenza come secondo argomento, l'indice finale come terzo argomento e la chiave di ricerca come quarto argomento.</p><p>Finché mantieni l'indice finale entro la lunghezza dell'array, il metodo dovrebbe funzionare senza problemi. Se usi un indice maggiore, otterrai l'eccezione <code>Array index out of range</code>.</p><p>Semplice, vero? Il metodo restituisce l'indice dell'elemento, se questo viene trovato. Ma cosa succede se non trova l'elemento indicato?</p><h2 id="cosa-succede-quando-arrays-binarysearch-non-trova-l-elemento-dato"><strong>Cosa succede quando <code>Arrays.binarySearch()</code> non trova l'elemento dato?</strong></h2><p>Ancora, secondo la <a href="https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#binarySearch(byte[],%20byte)">documentazione ufficiale</a> sul metodo <code>Arrays.binarySearch()</code>:</p><blockquote>Il metodo restituisce l'indice della chiave di ricerca, se contenuto nell'array all'interno dell'intervallo specificato; altrimenti <code>(-(<em><em>insertion point</em></em>) - 1)</code>.<br><br>"Insertion point" è definito come il punto in cui la chiave dovrebbe essere inserita nell'array: l'indice del primo elemento nell'intervallo maggiore della chiave, o <code>toIndex</code> (indice finale) se tutti gli elementi nell'intervallo sono minori della chiave specificata.<br><br>Nota che questo garantisce che il valore di ritorno sarà &gt;= 0 se e solo se la chiave è trovata.</blockquote><p>Non molto chiaro, vero? Provo a spiegare. La prima riga afferma che il metodo restituisce l'indice della chiave di ricerca se la chiave viene trovata nell'array.</p><p>Se non viene trovata, l'output sarà uguale al valore di <code>(-(<em><em>insertion point</em></em>) - 1)</code>. Qui, in base alla chiave di ricerca, <code>insertion point</code> può avere diversi valori.</p><p>Ipotizziamo di avere l'array <code>[5, 6, 7, 8, 9, 10]</code> e la chiave di ricerca <code>0</code>, che è chiaramente non presente nell'array. In questo caso, la chiave di ricerca è minore di tutti gli elementi dell'array. Ma il primo elemento maggiore della chiave di ricerca è <code>5</code>, quindi in questo caso il valore di <code>insertion point</code> sarà: </p><pre><code>(-(indice del primo elemento maggiore della chiave) - 1) = (0 - 1) = -1</code></pre><p>Possiamo verificarlo nello snippet di codice seguente:</p><pre><code class="language-java">package arrays;

import java.util.Arrays;

public class Main {

	public static void main(String[] args) {		
		int numeri[] = {5, 6, 7, 8, 9, 10};
		
		System.out.println(Arrays.binarySearch(numeri, 0)); // -1
	}
}
</code></pre><p>Di nuovo, ipotizziamo di avere l'array <code>[5, 6, 7, 8, 9, 10]</code> e la chiave di ricerca <code>12</code>, chiaramente non presente nell'array. In questo caso, la chiave di ricerca è maggiore di tutti gli elementi dell'array e il valore di <code>insertion point</code> sarà:</p><pre><code>(-(l'indice finale (-(6) - 1) = (-6 - 1) = -7</code></pre><p>Ricorda, quando non definisci manualmente un indice finale, il metodo usa la lunghezza dell'array come indice finale, che in questo caso è <code>6</code>.</p><p>Possiamo verificarlo nello snippet di codice seguente:</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {		
		int numeri[] = {5, 6, 7, 8, 9, 10};
		
		System.out.println(Arrays.binarySearch(numeri, 12)); // -7
	}
}
</code></pre><p>Tuttavia, i risultati cambieranno se definisci gli indici di partenza e di fine manualmente, in questo modo:</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {
		int numeri[] = {5, 6, 7, 8, 9, 10};
		
		int indicePartenza = 1;
		int indiceFine = 3;
		
		System.out.println(Arrays.binarySearch(numeri, indicePartenza, indiceFine, 5)); // -2
		System.out.println(Arrays.binarySearch(numeri, indicePartenza, indiceFine, 10)); // -4

	}
}
</code></pre><p>Prova tu stesso a calcolare i valori. Puoi anche usare il metodo <code>Arrays.binarySearch()</code> con dei caratteri, in questo modo:</p><pre><code class="language-java">import java.util.Arrays;

public class Main {

	public static void main(String[] args) {
		char vocali[] = {'a', 'e', 'i', 'o', 'u'};
		
		char chiave = 'i';
		int indicePartenza = 2;
		int indiceFine = 4;
		
		System.out.println(Arrays.binarySearch(vocali, indicePartenza, indiceFine, chiave));

	}
}
</code></pre><p>Lo stesso principio si applica in questo caso, quando la chiave di ricerca fornita non viene trovata. Ma per il confronto di un carattere nell'array e una data chiave di ricerca, sarà utilizzato il <a href="https://www.ascii-code.com/">codice ASCII</a> corrispondente al carattere. Quindi <code>A (65)</code> sarà minore di <code>a (97)</code>. Tienilo a mente quando controlli gli output del tuo programma.</p><h2 id="in-conclusione"><strong>In conclusione</strong></h2><p>Questo era praticamente tutto per questo metodo. Spero che adesso tu sia in grado di capire come funziona <code>Arrays.binarySearch()</code>.</p><p>Buona programmazione!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Getter e Setter in Java ]]>
                </title>
                <description>
                    <![CDATA[ I getter e i setter vengono usati per proteggere dati, in particolar modo quando si creano delle classi. Per ogni variabile di istanza, un metodo getter restituisce il suo valore, mentre un metodo setter ne imposta o ne aggiorna il valore. Per questo motivo, getter e setter sono anche conosciuti ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/getter-e-setter-in-java/</link>
                <guid isPermaLink="false">62fa0a7003346c07472e887e</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Dario Di Cillo ]]>
                </dc:creator>
                <pubDate>Fri, 02 Sep 2022 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2022/08/getters.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/java-getters-and-setters/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Getters and Setters in Java Explained</a>
      </p><p>I getter e i setter vengono usati per proteggere dati, in particolar modo quando si creano delle classi.</p><p>Per ogni variabile di istanza, un metodo getter restituisce il suo valore, mentre un metodo setter ne imposta o ne aggiorna il valore. Per questo motivo, getter e setter sono anche conosciuti rispettivamente come <em><em>accessor</em></em> e <em><em>mutator</em></em>.</p><p>Per convenzione, i getter iniziano con la parola "get" e i setter iniziano con la parola "set", seguita dal nome della variabile. In entrambi i casi la prima lettera del nome della variabile è maiuscola:</p><pre><code class="language-java">public class Vehicle {
  private String color;
  
  // Getter
  public String getColor() {
    return color;
  }
  
  // Setter
  public void setColor(String c) {
    this.color = c;
  }
}</code></pre><p>Il metodo getter restituisce il valore dell'attributo. Il metodo setter prende un parametro e lo assegna all'attributo.</p><p>Una volta che il getter e il setter sono stati definiti, li possiamo usare nel main:</p><pre><code class="language-java">public static void main(String[] args) {
  Vehicle v1 = new Vehicle();
  v1.setColor("Red");
  System.out.println(v1.getColor());
}

// l'output è "Red"</code></pre><p>Getter e setter permettono di avere controllo su dei valori. Potresti anche validare il valore dato nel setter prima di impostarlo effettivamente.</p><h3 id="perch-usare-getter-e-setter"><strong>Perché usare getter e setter?</strong></h3><p>Getter e setter ti permettono di controllare il modo in cui le variabili nel tuo codice sono consultate e aggiornate. Ad esempio, considera questo metodo setter:</p><pre><code class="language-java">public void setNumber(int number) {
  if (number &lt; 1 || number &gt; 10) {
    throw new IllegalArgumentException();
  }
  this.number = num;
}</code></pre><p>Usando il metodo <code>setNumber</code>, puoi essere sicuro che il valore di <code>number</code> sia sempre tra 1 e 10. Molto più conveniente rispetto ad aggiornare direttamente la variabile <code>number</code>:</p><pre><code class="language-java">obj.number = 13;</code></pre><p>Se aggiorni direttamente <code>number</code>, è possibile che si verifichino dei possibili effetti indesiderati da qualche parte nel codice. In quest'esempio, impostare <code>number</code> su 13 viola il vincolo che volevamo stabilire, per cui il suo valore deve essere compreso tra 1 e 10.</p><p>Rendere <code>number</code> una variabile privata e usare il metodo <code>setNumber</code> impedisce che questo accada.</p><p>D'altra parte, l'unico modo per leggere il valore di <code>number</code> è l'uso di un metodo getter:</p><pre><code class="language-java">public int getNumber() {
  return this.number;
}</code></pre> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Come programmare un cifrario di Cesare: un'introduzione alla codifica di base ]]>
                </title>
                <description>
                    <![CDATA[ Il cifrario di Cesare è una famosa attuazione della crittografia risalente ai suoi primordi. Prende una frase e la riorganizza, basandosi su una chiave che viene adoperata sull'alfabeto. Ad esempio, considera la chiave 3 e la frase  > Mi piace indossare i cappelli.  Quando la frase viene codificata ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/come-programmare-un-cifrario-di-cesare-unintroduzione-alla-codifica-di-base/</link>
                <guid isPermaLink="false">62bb026a7e58e706f822c24b</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Algoritmi ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Dario Di Cillo ]]>
                </dc:creator>
                <pubDate>Fri, 08 Jul 2022 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2022/06/0_tuogeHoQ53SQACY-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/how-to-code-the-caesar-cipher-an-introduction-to-basic-encryption-3bf77b4e19f7/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to code the Caesar Cipher: an introduction to basic encryption</a>
      </p><p>Il cifrario di Cesare è una famosa attuazione della crittografia risalente ai suoi primordi. Prende una frase e la riorganizza, basandosi su una chiave che viene adoperata sull'alfabeto. Ad esempio, considera la chiave 3 e la frase </p><blockquote>Mi piace indossare i cappelli. </blockquote><p>Quando la frase viene codificata usando la chiave 3, diventa:</p><blockquote>Pl sldfh lqgrvvduh l fdsshool.</blockquote><p>In questo modo, è difficile leggere il messaggio, che può passare inosservato.</p><p>Mentre questo è un esempio di codifica m0lto semplice, è un progetto perfetto su cui far pratica per chi sta imparando a programmare.</p><h4 id="comprendere-il-cifrario"><strong>Comprendere il cifrario</strong></h4><p>Per implementare questo codice, almeno in Java, avrai bisogno di riflettere a fondo su ciò che è stato fatto. Quindi, vediamo quali sono i passaggi fondamentali da considerare per questo codice. </p><p>Step 1: identifica il carattere nella frase.</p><p>Step 2: trova la posizione del carattere nell'alfabeto.</p><p>Step 3: identifica la somma di posizione del carattere + posizione della chiave nell'alfabeto.</p><p>Note* se la posizione del carattere + chiave &gt; 26, torna indietro e ricomincia a contare da 1.</p><p>Step 4: costruisci una nuova frase usando i nuovi caratteri al posto di quelli originali.</p><p>Step 5: ripeti fino a raggiungere la lunghezza della frase (loop for).</p><p>Step 6: restituisci il risultato.</p><h4 id="codificare-il-cifrario"><strong>Codificare il cifrario</strong></h4><p>Questi sono dei buoni step da seguire, ma dovremmo pensare a cosa ci serve fare in termini di codice.</p><p>Step 0: crea una funzione che accetta un messaggio e una chiave.</p><p>Qualcosa del genere:</p><pre><code>public String Encrypt(String message, int key) {

}</code></pre><p>Step 1: identifica il carattere nella frase.</p><p>Per farlo, avremo bisogno di stabilire un alfabeto a cui fare riferimento.</p><p>Crea una variabile <code>alphabet</code> che contiene le 26 lettere dell'alfabeto.</p><pre><code>String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String alphabet2 = alphabet.toLowerCase();</code></pre><p>Step 2: trova la posizione del carattere nell'alfabeto.</p><p>Poi crea un loop for che itera su ogni carattere del messaggio. Sarà più semplice svolgere quest'operazione se creiamo uno <code>StringBuilder</code>.</p><pre><code>StringBuilder encrypted = new StringBuilder(message);
for (int q = 0; q &lt; encrypted.length(); q++) {
    char currchar = encrypted.charAt(q);
    int index = alphabet.indexOf(currchar);
}</code></pre><p>A questo punto, dovremmo assicurarci che la posizione corrisponda a una lettera.</p><pre><code>if (index != -1) {}</code></pre><p>Step 3: &nbsp;identifica la somma di posizione del carattere + posizione della chiave nell'alfabeto.</p><p>Se è una lettera, allora dobbiamo trovare la posizione nell'alfabeto modificato, Non abbiamo ancora creato una variabile per l'alfabeto modificato, quindi dovremmo farlo adesso.</p><p>Step 4: costruisci una nuova frase usando i nuovi caratteri al posto di quelli originali.</p><p>Una volta trovato il valore nell'alfabeto modificato, dovremmo impostarlo sulla stessa posizione nello StringBuilder che abbiamo creato.</p><pre><code>public String Encryption(String input, int key) {
        StringBuilder encrypted = new StringBuilder(input);
        String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String alphabet2 = alphabet.toLowerCase();
        String keyedalphabet = alphabet.substring(key) + alphabet.substring(0, key);
        for (int q = 0; q &lt; encrypted.length(); q++) {
            char currChar = encrypted.charAt(q);
            int index = alphabet.indexOf(currChar);
            if (index != -1) {
                char newChar = keyedalphabet.charAt(index);
                encrypted.setCharAt(q, newChar);
            }</code></pre><p>Step 5: ripeti fino a raggiungere la lunghezza della frase (loop for).</p><p>Ora, abbiamo controllato se il carattere è maiuscolo, ma dobbiamo controllare anche se è minuscolo. Per farlo, dobbiamo accedere a <code>alphabet2</code> che abbiamo creato precedentemente.</p><pre><code>index = alphabet2.indexOf(currChar);
if (index != -1) {
    String keyedalphabet2 = keyedalphabet.toLowerCase();
    char newChar = keyedalphabet2.charAt(index);
    encrypted.setCharAt(q, newChar);
}</code></pre><p>Step 6: restituisci il risultato.</p><p>Una volta completato il loop for, tutto ciò che ci resta da fare è restituire la stringa.</p><pre><code>public String Encryption(String input, int key) {
    StringBuilder encrypted = new StringBuilder(input);
    String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    String alphabet2 = alphabet.toLowerCase();
    String keyedalphabet = alphabet.substring(key) + alphabet.Asubstring(0, key);
    for (int q = 0; q &lt; encrypted.length(); q++) {
        char currChar = encrypted.charAt(q);
        int index = alphabet.indexOf(currChar);
        if (index != -1) {
            char newChar = keyedalphabet.charAt(index);
            encrypted.setCharAt(q, newChar);
        }
        index = alphabet2.indexOf(currChar);
        if (index != -1) {
            String keyedalphabet2 = keyedalphabet.toLowerCase();
            char newChar = keyedalphabet2.charAt(index);
            encrypted.setCharAt(q, newChar);
        }
    }
    return encrypted
}</code></pre><p>Step 7: Debug.</p><p>Un momento! Così non funzionerà! <code>encrypted</code> non è una stringa, ma uno <code>StringBuilder</code> e questa funzione richiede specificatamente che venga restituita una stringa.</p><p>Fortunatamente, esiste una funzione molto semplice per rimediare a &nbsp;questa svista.</p><pre><code>public String Encryption(String input, int key) {
    StringBuilder encrypted = new StringBuilder(input);
    String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    String alphabet2 = alphabet.toLowerCase();
    String keyedalphabet = alphabet.substring(key) + alphabet.substring(0, key);
    for (int q = 0; q &lt; encrypted.length(); q++) {
        char currChar = encrypted.charAt(q);
        int index = alphabet.indexOf(currChar);
        if (index != -1) {
            char newChar = keyedalphabet.charAt(index);
            encrypted.setCharAt(q, newChar);
        }
        index = alphabet2.indexOf(currChar);
        if (index != -1) {
            String keyedalphabet2 = keyedalphabet.toLowerCase();
            char newChar = keyedalphabet2.charAt(index);
            encrypted.setCharAt(q, newChar);
        }
    }
    return encrypted.toString();
}</code></pre><p>Ecco come puoi ottenere la versione codificata della tua frase originale. Prova tu stesso!</p><p>Grazie per aver letto quest'articolo.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Generatore di numeri casuali in Java – Come generare interi con Math Random ]]>
                </title>
                <description>
                    <![CDATA[ I numeri casuali generati da computer sono divisi in due categorie: numeri casuali veri e numeri pseudo-casuali.  I numeri casuali veri vengono generati sulla base di fattori esterni. Ad esempio, ottenendo la casualità usando i rumori circostanti. Ma generare numeri casuali veri in questo modo, richiede molto tempo. Quindi, ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/generatore-di-numeri-casuali-in-java-come-generare-interi-con-math-random/</link>
                <guid isPermaLink="false">62baf9547e58e706f822c150</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Dario Di Cillo ]]>
                </dc:creator>
                <pubDate>Thu, 07 Jul 2022 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2022/06/java-rng.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/generate-random-numbers-java/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Java Random Number Generator – How to Generate Integers With Math Random</a>
      </p><p>I numeri casuali generati da computer sono divisi in due categorie: numeri casuali veri e numeri pseudo-casuali. </p><p>I numeri casuali veri vengono generati sulla base di fattori esterni. Ad esempio, ottenendo la casualità usando i rumori circostanti.</p><p>Ma generare numeri casuali veri in questo modo, richiede molto tempo. Quindi, possiamo utilizzare dei numeri pseudo-casuali che vengono generati usando un algoritmo e un valore iniziale.</p><p>I numeri pseudo-casuali sono adeguati per la maggior parte degli scopi. Ad esempio, puoi usarli in crittografia, per realizzare giochi con dadi o carte e per creare numeri OTP (one-time password).</p><p>In quest'articolo, impareremo come generare numeri pseudo-casuali usando <code>Math.random()</code> in Java.</p><h2 id="1-usare-math-random-per-generare-interi"><strong>1. Usare Math.random() per generare interi</strong></h2><p><code>Math.random()</code> restituisce un numero pseudo-casuale di tipo double, maggiore di o uguale a zero e minore di uno.</p><p>Proviamolo in questo blocco di codice:</p><pre><code class="language-java">    public static void main(String[] args) {
        double randomNumber = Math.random();
        System.out.println(randomNumber);
    }
    // output #1 = 0.5600740702032417
    // output #2 = 0.04906751303932033</code></pre><p><code>randomNumber</code> ti darà numeri casuali diversi a ogni esecuzione.</p><p>Diciamo di voler generare numeri casuali in un range specifico, per esempio, da zero a quattro.</p><pre><code class="language-java">    // genera numeri casuali tra 0 e 4
    public static void main(String[] args) {
        // Math.random() genera un numero casuale tra 0.0 e 0.999
        // Quindi, Math.random()*5 è un numero tra 0.0 e 4.999
        double doubleRandomNumber = Math.random() * 5;
        System.out.println("doubleRandomNumber = " + doubleRandomNumber);
        // converti il double in numero intero
        int randomNumber = (int)doubleRandomNumber;
        System.out.println("randomNumber = " + randomNumber);
    }
    /* Output #1
    doubleRandomNumber = 2.431392914284627
    randomNumber = 2
    */</code></pre><p>Quando convertiamo un double a int, il valore int mantiene soltanto la parte intera del numero.</p><p>Ad esempio, nel codice qui sopra, <code>doubleRandomNumber</code> è <code>2.431392914284627</code>. La parte intera di <code>doubleRandomNumber</code> è <code>2</code> e la parte decimale (i numeri dopo il punto) è <code>431392914284627</code>. Quindi, <code>randomNumber</code> manterrà soltanto la parte intera del numero <code>2</code>.</p><p>Puoi leggere di più sul metodo <code>Math.random()</code> nella <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html">documentazione Java</a>.</p><p>Usare <code>Math.random()</code> non è l'unico modo per generare numeri casuali in Java. Adesso, considereremo come generare numeri casuali usando la classe Random.</p><h2 id="2-usare-la-classe-random-per-generare-interi"><strong>2. Usare la classe Random per generare interi</strong></h2><p>Nella classe Random, abbiamo molte metodi d'istanza che forniscono numeri casuali. In questa sezione, vedremo due metodi d'istanza: <code>nextInt(int bound)</code> e <code>nextDouble()</code>.</p><h3 id="come-usare-il-metodo-nextint-int-bound-"><strong>Come usare il metodo nextInt(int bound)</strong></h3><p><code>nextInt(int bound)</code> restituisce un numero pseudo-casuale di tipo int, maggiore di o uguale a zero e minore del valore bound.</p><p>Il parametro <code>bound</code> specifica il range. Ad esempio, se specifichiamo il bound come 4, <code>nextInt(4)</code> restituirà un valore di tipo int, maggiore o uguale a zero e minore di quattro. 0,1,2,3 sono i possibili risultati di <code>nextInt(4)</code> .</p><p>Dato che questo è un metodo d'istanza, dovremmo creare un oggetto random per utilizzarlo. Proviamo.</p><pre><code class="language-java">    public static void main(String[] args) {
        // crea oggetto Random
        Random random = new Random();
        // genera numero casuale tra 0 e 3
        int number = random.nextInt(4);
        System.out.println(number);
    }</code></pre><h3 id="come-usare-il-metodo-nextdouble-"><strong>Come usare il metodo nextDouble()</strong></h3><p>Analogamente a <code>Math.random()</code>, <code>nextDouble()</code> restituisce un numero pseudo-casuale di tipo double, maggiore di o uguale a zero e minore di uno.</p><pre><code class="language-java">    public static void main(String[] args) {
        // crea oggetto Random
        Random random = new Random();
        // genera numero random maggiore o uguale a 0.0 e minore di 1.0
        double number = random.nextDouble();
        System.out.println(number);
    }</code></pre><p>Per altre informazioni, puoi leggere la <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Random.html">documentazione Java</a>.</p><h2 id="quale-metodo-scegliere"><strong>Quale metodo scegliere?</strong></h2><p><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#random--">Math.random()</a></code> utilizza la classe random. Se nella nostra applicazione vogliamo solo numeri pseudo-casuali di tipo double, allora possiamo usare <code>Math.random()</code>.</p><p>Altrimenti, possiamo usare la classe random dato che offre svariati metodi per generare numeri pseudo-casuali in tipi diversi come <code>nextInt()</code>, <code>nextLong()</code>, <code>nextFloat()</code> e <code>nextDouble()</code>.</p><p>Grazie per aver letto quest'articolo.</p><p>Photo image by <a href="https://unsplash.com/@brett_jordan?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Brett Jordan</a> on <a href="https://unsplash.com/s/photos/random-numbers?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p><p><strong>Buona programmazione<strong>!</strong></strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Java da String a Int - Come convertire una stringa in un numero intero ]]>
                </title>
                <description>
                    <![CDATA[ Gli oggetti stringa sono rappresentati come stringhe di caratteri. Se hai lavorato in Java Swing, sai che ha componenti come JTextField e JTextArea che usiamo per ottenere i nostri input dall'interfaccia grafica. Inoltre, prende il nostro input come una stringa.  Se vogliamo fare una semplice calcolatrice usando Swing, dobbiamo ]]>
                </description>
                <link>https://www.freecodecamp.org/italian/news/java-da-string-a-int-come-convertire-una-stringa-in-un-numero-intero/</link>
                <guid isPermaLink="false">62a85a7ea3647806dd4ed8cf</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ilenia Magoni ]]>
                </dc:creator>
                <pubDate>Mon, 27 Jun 2022 05:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/italian/news/content/images/2022/06/Untitled-design.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Articolo originale:</strong> <a href="https://www.freecodecamp.org/news/java-string-to-int-how-to-convert-a-string-to-an-integer/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Java String to Int – How to Convert a String to an Integer</a>
      </p><p>Gli oggetti stringa sono rappresentati come stringhe di caratteri.</p><p>Se hai lavorato in Java Swing, sai che ha componenti come JTextField e JTextArea che usiamo per ottenere i nostri input dall'interfaccia grafica. Inoltre, prende il nostro input come una stringa. </p><p>Se vogliamo fare una semplice calcolatrice usando Swing, dobbiamo scoprire come convertire una stringa in un numero intero. Questo ci porta alla domanda, come facciamo a convertire una stringa in un numero intero?</p><p>In Java, possiamo usare <code>Integer.valueOf()</code> e <code>Integer.parseInt()</code> per convertire una stringa in un numero intero.</p><h2 id="1-usare-integer-parseint-per-convertire-una-stringa-in-un-numero-intero"><strong>1. Usare Integer.parseInt() per convertire una stringa in un numero intero</strong></h2><p>Questo metodo restituisce la stringa come un <strong>tipo primitivo int</strong>. Se la stringa non contiene un numero intero valido allora dà una eccezione <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html">NumberFormatException</a>.</p><p>Quindi, ogni volta che convertiamo una stringa in un numero intero, dobbiamo gestire questa eccezione mettendo il codice dentro un blocco try-catch.</p><p>Consideriamo un esempio di conversione da una stringa ad un numero intero usando <code>Integer.parseInt()</code>:</p><pre><code class="language-java">        String str = "25";
        try{
            int number = Integer.parseInt(str);
            System.out.println(number); // output = 25
        }
        catch (NumberFormatException ex){
            ex.printStackTrace();
        }</code></pre><p>Cerchiamo di rompere questo codice scrivendo un numero intero non valido:</p><pre><code class="language-java">     	String str = "25T";
        try{
            int number = Integer.parseInt(str);
            System.out.println(number);
        }
        catch (NumberFormatException ex){
            ex.printStackTrace();
        }</code></pre><p>Come puoi vedere nel codice sopra, abbiamo provato a convertire <code>25T</code> in un numero intero. Questo non è un input valido, quindi dà un errore <code>NumberFormatException</code>.</p><p>Ecco l'output del codice sopra:</p><pre><code class="language-java">java.lang.NumberFormatException: For input string: "25T"
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Integer.parseInt(Integer.java:580)
	at java.lang.Integer.parseInt(Integer.java:615)
	at OOP.StringTest.main(StringTest.java:51)</code></pre><p>Come passo successivo, consideriamo come convertire una stringa in un numero intero, usando il metodo <code>Integer.valueOf()</code> method.</p><h2 id="2-usare-integer-valueof-per-convertire-una-stringa-in-un-numero-intero">2. Usare Integer.valueOf() per convertire una stringa in un numero intero</h2><p>Questo metodo restituisce la stringa come <strong>oggetto numero intero</strong>. Se guardi sulla <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#valueOf(java.lang.String)">documentazione di Java</a>, <code>Integer.valueOf()</code> restituisce un oggetto numero intero che è equivalente a <code>new Integer(Integer.parseInt(s))</code>.</p><p>Metteremo il nostro codice in un blocco try-catch quando usiamo questo metodo. Consideriamo un esempio usando il metodo <code>Integer.valueOf()</code>:</p><pre><code class="language-java">        String str = "25";
        try{
            Integer number = Integer.valueOf(str);
            System.out.println(number); // output = 25
        }
        catch (NumberFormatException ex){
            ex.printStackTrace();
        }</code></pre><p>Ora, proviamo a romperlo inserendo un numero intero non valido:</p><pre><code class="language-java">        String str = "25TA";
        try{
            Integer number = Integer.valueOf(str);
            System.out.println(number); 
        }
        catch (NumberFormatException ex){
            ex.printStackTrace();
        }</code></pre><p>Come l'esempio precedente, il codice sopra darà un errore.</p><p>Ecco l'output del codice sopra:</p><pre><code class="language-java">java.lang.NumberFormatException: For input string: "25TA"
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Integer.parseInt(Integer.java:580)
	at java.lang.Integer.valueOf(Integer.java:766)
	at OOP.StringTest.main(StringTest.java:42)</code></pre><p>Prima di usare il metodo sopra menzionato, possiamo anche creare un metodo per controllare se la stringa input è numerica o meno.</p><p>Ho creato un semplice metodo per controllare se la stringa inserita è numerica o no:</p><pre><code class="language-java">public class StringTest {
    public static void main(String[] args) {
        String str = "25";
        String str1 = "25.06";
        System.out.println(isNumeric(str));
        System.out.println(isNumeric(str1));
    }

    private static boolean isNumeric(String str){
        return str != null &amp;&amp; str.matches("[0-9.]+");
    }
}</code></pre><p>L'output è:</p><pre><code class="language-java">true
true</code></pre><p>Il metodo <code>isNumeric()</code> prende una stringa come argomento. Prima controlla se è <code>null</code> o meno. Poi usa il metodo <code>matches()</code> per vedere se contiene le cifre da 0 a 9 e il carattere punto.</p><p>Questo è un semplice modo per controllare se è un valore numerico. Puoi scrivere tu stesso o cercare su Google espressioni regolari più complesse a seconda del tuo caso di utilizzo.</p><p>È buona pratica controllare se la stringa input è numerica o no prima di provare a trasformarla in un numero intero.</p><p>Grazie per aver letto quest'articolo.</p><p>Immagine di <a href="https://unsplash.com/@itfeelslikefilm?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">🇸🇮 Janko Ferlič</a> su <a href="https://unsplash.com/collections/139346/soul-care?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p><p><strong>Buona programmazione!</strong></p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
