<?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[ Aprenda a codificar - de graça. Tutoriais de programação em Python, JavaScript, Linux e muito mais. ]]>
        </description>
        <link>https://www.freecodecamp.org/portuguese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Java - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Thu, 28 May 2026 16:39:31 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/tag/java/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Como escrever testes unitários em Java ]]>
                </title>
                <description>
                    <![CDATA[ Digamos que você está desenvolvendo uma aplicação. Depois de longas horas programando, você consegue criar algumas funcionalidades legais. Agora, você quer ter certeza de que as funcionalidades estão do jeito que você quer. Isso envolve testar se cada parte do código funciona como esperado. Esse procedimento é conhecido como teste ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-escrever-testes-unitarios-em-java/</link>
                <guid isPermaLink="false">6683675a23266d03fc8b8034</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kris Lagerström ]]>
                </dc:creator>
                <pubDate>Tue, 09 Jul 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/07/photo-1498050108023-c5249f4df085.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/java-unit-testing/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Write Unit Tests in Java</a>
      </p><p>Digamos que você está desenvolvendo uma aplicação. Depois de longas horas programando, você consegue criar algumas funcionalidades legais. Agora, você quer ter certeza de que as funcionalidades estão do jeito que você quer.</p><p>Isso envolve testar se cada parte do código funciona como esperado. Esse procedimento é conhecido como teste unitário. Diferentes linguagens fornecem seus próprios <em>frameworks </em>para testes.</p><p>Neste artigo, vou mostrar como escrever testes unitários em Java. Primeiro, explicarei o que o teste envolve e alguns conceitos que você precisará saber. Então, mostrarei alguns exemplos para ajudar você a entender melhor.</p><p>Para este artigo, assumo que você esteja familiarizado com o Java e com o IDE IntelliJ.</p><h2 id="configura-o-do-projeto">Configuração do projeto</h2><p>Para este projeto, usarei o IDE IntelliJ. Se você não o tiver, siga <a href="https://www.jetbrains.com/help/idea/installation-guide.html#standalone">este guia</a> (em inglês) para instalar o IDE.</p><p>Neste projeto, usaremos as bibliotecas JUnit e Mockito para testes. Elas são as bibliotecas mais usadas para testes em Java. Você entenderá como essas bibliotecas são usadas à medida que avança pelo artigo.</p><p>Para configurar o JUnit, siga as etapas abaixo, <a href="https://www.jetbrains.com/help/idea/junit.html">conforme descrito neste guia</a> (em inglês):</p><ol><li>No menu principal, selecione File &gt; New &gt; Project.</li><li>Selecione <strong>New Project.</strong> Especifique um nome para o projeto – eu darei o nome de <code>junit-testing-tutorial</code>.</li><li>Selecione <strong>Maven</strong> como a ferramenta de build e, na linguagem, selecione <strong>Java</strong>.</li><li>Na lista <strong>JDK</strong>, selecione o JDK que você deseja usar no projeto.</li><li>Clique em <strong>Create.</strong></li><li>Abra o arquivo <strong>pom.xml</strong> no diretório raiz do seu projeto.</li><li>No pom.xml, dentro das tags <code>&lt;dependencies&gt;&lt;/dependencies&gt;</code>, pressione <code>Alt + Insert</code> (ou <code>Cmd + Insert</code> no macOS), e selecione <strong>Generate Dependency.</strong></li><li>Isso abrirá uma janela de ferramentas. Digite <code>org.junit.jupiter:junit-jupiter</code> no campo de pesquisa. Localize a dependência necessária e clique no botão <strong>Add</strong>.</li><li>Agora, clique em <strong>Load Maven Changes</strong> na notificação que aparece no canto superior direito no editor.</li></ol><p>Agora, para configurar o Mockito, adicione essas duas dependências no seu <code>pom.xml</code>:</p><pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.mockito&lt;/groupId&gt;
    &lt;artifactId&gt;mockito-inline&lt;/artifactId&gt;
    &lt;version&gt;5.2.0&lt;/version&gt;
    &lt;scope&gt;compile&lt;/scope&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.mockito&lt;/groupId&gt;
    &lt;artifactId&gt;mockito-junit-jupiter&lt;/artifactId&gt;
    &lt;version&gt;5.2.0&lt;/version&gt;
    &lt;scope&gt;compile&lt;/scope&gt;
&lt;/dependency&gt;</code></pre><p><strong>Observação</strong>: a versão pode ser diferente, dependendo da época em que você está lendo este artigo.</p><p>Para completar a configuração, crie uma classe <code>Welcome</code> e defina sua função principal lá.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-12-at-6.14.33-PM.png" class="kg-image" alt="Screenshot-2023-03-12-at-6.14.33-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/07/Screenshot-2023-03-12-at-6.14.33-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/07/Screenshot-2023-03-12-at-6.14.33-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/07/Screenshot-2023-03-12-at-6.14.33-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-12-at-6.14.33-PM.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1051" loading="lazy"><figcaption>Estrutura de pastas e o método principal</figcaption></figure><h2 id="o-que-um-teste-unit-rio">O que é um teste unitário?</h2><p>Os testes unitários envolvem testar cada componente do seu código para ver se ele funciona como esperado. Eles isolam cada método individual do seu código e executam testes nele. Os testes unitários ajudam a garantir que seu software está funcionando como esperado antes de ser lançado.</p><p>Como desenvolvedor, você escreverá testes unitários assim que terminar de escrever um trecho de código. Você pode se perguntar se essa não é a tarefa de um testador. De certo modo, sim. Um testador é responsável por testar o software. No entanto, examinar cada linha de código coloca muita pressão no testador. Portanto, é uma boa prática para os desenvolvedores escreverem testes para seu próprio código também.</p><p>O objetivo do teste unitário é garantir que qualquer nova funcionalidade não interrompa a funcionalidade existente. Também ajuda a identificar quaisquer problemas ou <em>bugs </em>mais cedo no processo de desenvolvimento e ajuda a garantir que o código atenda aos padrões de qualidade definidos pela organização.</p><h3 id="o-que-fazer-e-o-que-n-o-fazer-ao-realizar-testes-unit-rios">O que fazer e o que não fazer ao realizar testes unitários</h3><p>Lembre-se das seguintes diretrizes ao escrever testes para seus métodos:</p><ul><li>Teste se a saída esperada de um método corresponde à saída real.</li><li>Teste se as funções chamadas dentro do método estão ocorrendo o número desejado de vezes.</li><li>Não tente testar código que não faça parte do método que está sendo testado.</li><li>Não faça chamadas de API, conexões de banco de dados ou solicitações de rede ao escrever seus testes.</li></ul><p>Agora, vamos ver alguns conceitos que você precisa saber antes de começarmos a escrever testes.</p><h3 id="afirma-es">Afirmações</h3><p>As afirmações (em inglês, <em>assertions</em>) determinam se seu teste é aprovado ou reprovado. Elas comparam o valor de retorno esperado de um método com o valor real. Há uma série de afirmações que você pode fazer no final do seu teste.</p><p>A classe <code>Assertions</code> no JUnit consiste em métodos estáticos que fornecem várias condições para decidir se o teste é aprovado ou não. Veremos esses métodos à medida que eu o guie por cada exemplo.</p><h3 id="mocking"><em>Mocking</em></h3><p>A classe cujos métodos você está testando pode ter algumas dependências externas. Como mencionado anteriormente, você não deve tentar testar código que não faça parte da função que está sendo testada.</p><p>Nos casos em que sua função usa uma classe externa, porém, é uma boa prática fazer um <em>mock </em>dessa classe, ou seja, ter valores de mock-up (algo como "simulações", em português) em vez dos valores reais. Usaremos a biblioteca Mockito para esse fim.</p><h3 id="stubbing-de-m-todo"><em>Stubbing</em> de método</h3><p>As dependências externas podem não se limitar apenas às classes, mas também a certos métodos. O <a href="https://pt.wikipedia.org/wiki/Stub">stubbing de método</a> deve ser feito quando sua função está chamando uma função externa em sua implementação. Nesse caso, você faz com que essa função retorne o valor que você deseja em vez de chamar o método real.</p><p>Por exemplo, o método que você está testando (A) está chamando um método externo (B) em sua implementação. B faz uma consulta ao banco de dados, buscando todos os alunos com notas maiores que 80. Fazer uma chamada real ao banco de dados não é uma boa prática aqui. Portanto, você faz um <em>stub </em>do método e o faz retornar uma lista fictícia de alunos que você precisa para testar.</p><p>Você entenderá isso melhor com exemplos. Existem muitos outros conceitos que fazem parte dos testes em Java. Por enquanto, esses três são suficientes para você começar.</p><h2 id="passos-a-serem-realizados-durante-os-testes">Passos a serem realizados durante os testes</h2><ol><li>Inicialize os parâmetros necessários que você precisará para executar o teste.</li><li>Crie objetos de <em>mock-up</em> e faça um <em>stub</em> de qualquer método se necessário.</li><li>Chame o método que você está testando com os parâmetros que você inicializou na etapa 1.</li><li>Adicione uma afirmação para verificar o resultado do seu teste. Isso decidirá se o teste é aprovado.</li></ol><p>Você entenderá essas etapas melhor com exemplos. Vamos começar com um teste básico primeiro.</p><h2 id="como-escrever-o-primeiro-teste">Como escrever o primeiro teste</h2><p>Vamos escrever uma função simples que compara dois números. Ela retorna <code>1</code> se o primeiro número for maior que o segundo ou <code>-1</code>, do contrário.</p><p>Colocaremos essa função dentro de uma classe <code>Basics</code>:</p><pre><code class="language-java">public class Basics {
    public int compare(int n1, int n2) {
        if (n1 &gt; n2) return 1;
        return -1;
    }
}</code></pre><p>Bem simples! Vamos escrever o teste para essa classe. Todos os seus testes devem estar localizados dentro da pasta <code>test</code>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-13-at-5.12.04-PM.png" class="kg-image" alt="Screenshot-2023-03-13-at-5.12.04-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/07/Screenshot-2023-03-13-at-5.12.04-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/07/Screenshot-2023-03-13-at-5.12.04-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/07/Screenshot-2023-03-13-at-5.12.04-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-13-at-5.12.04-PM.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="829" loading="lazy"><figcaption>Estrutura de pastas</figcaption></figure><p>Dentro da pasta <code>test</code>, crie uma classe <code>BasicTests</code>, onde você escreverá seus testes para essa classe. O nome da classe não importa, mas é uma boa prática segregar os testes de acordo com cada classe. Além disso, siga uma estrutura de pasta semelhante à do seu código principal.</p><pre><code class="language-java">public class BasicTests {
    // Seus testes vêm aqui
}</code></pre><p>Os testes unitários são basicamente um conjunto de métodos que você define para testar cada método da sua classe. Dentro da classe acima, crie um método <code>compare()</code>, com um tipo de retorno de <code>void</code>. Novamente, você pode nomear o método como quiser.</p><pre><code>@Test
public void compare() {

}</code></pre><p>A anotação <code>@Test</code> indica que esse método deve ser executado como um caso de teste.</p><p>Agora, para testar o método, você precisa criar o objeto da classe acima e chamar o método passando alguns valores.</p><pre><code class="language-java">Basics basicTests = new Basics();
int value = basicTests.compare(2, 1);</code></pre><p>Agora, use o método <code>assertEquals()</code> da classe <code>Assertions</code> para verificar se o valor retornado corresponde ao valor esperado.</p><pre><code class="language-java">Assertions.assertEquals(1, value);</code></pre><p>Nosso teste deve ser aprovado, pois o valor retornado pelo método corresponde ao valor esperado. Para verificar, execute o teste clicando com o botão direito na seta verde ao lado do método de teste.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-13-at-5.30.14-PM.png" class="kg-image" alt="Screenshot-2023-03-13-at-5.30.14-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/07/Screenshot-2023-03-13-at-5.30.14-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/07/Screenshot-2023-03-13-at-5.30.14-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/07/Screenshot-2023-03-13-at-5.30.14-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-13-at-5.30.14-PM.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="825" loading="lazy"><figcaption>Executando um teste</figcaption></figure><p>Os resultados do seu teste serão mostrados abaixo.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-13-at-5.32.06-PM.png" class="kg-image" alt="Screenshot-2023-03-13-at-5.32.06-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/07/Screenshot-2023-03-13-at-5.32.06-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/07/Screenshot-2023-03-13-at-5.32.06-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/07/Screenshot-2023-03-13-at-5.32.06-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-13-at-5.32.06-PM.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1253" loading="lazy"><figcaption>Resultados do teste</figcaption></figure><h2 id="mais-exemplos-de-teste">Mais exemplos de teste</h2><p>No teste acima, apenas testamos um cenário. Quando há ramificações na função, você precisa escrever testes para cada condição. Vamos introduzir algumas ramificações adicionais na função acima.</p><pre><code class="language-java">public int compare(int n1, int n2) {
    if (n1 &gt; n2) return 1;
    else if (n1 &lt; n2) return -1;
    return 0;
}</code></pre><p>Já testamos o primeiro ramo, então vamos escrever testes para os outros dois.</p><pre><code>@Test
@DisplayName("Primeiro número é menor que o segundo")
public void compare2() {
    Basics basicTests = new Basics();
    int value = basicTests.compare(2, 3);
    Assertions.assertEquals(-1, value);
}</code></pre><p>A anotação <code>@DisplayName</code> exibe o texto em vez do nome do método abaixo. Vamos executar o teste.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-13-at-6.01.15-PM.png" class="kg-image" alt="Screenshot-2023-03-13-at-6.01.15-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/07/Screenshot-2023-03-13-at-6.01.15-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/07/Screenshot-2023-03-13-at-6.01.15-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/07/Screenshot-2023-03-13-at-6.01.15-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-13-at-6.01.15-PM.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="438" loading="lazy"><figcaption>Teste aprovado</figcaption></figure><p>Para o caso em que os dois números são iguais:</p><pre><code class="language-java">@Test
@DisplayName("Primeiro número é igual ao segundo")
public void compare3() {
    Basics basicTests = new Basics();
    int value = basicTests.compare(2, 2);
    Assertions.assertEquals(0, value);
}</code></pre><h3 id="ordenando-um-array">Ordenando um <em>array</em></h3><p>Agora, vamos escrever o teste para o seguinte código que ordena um <em>array</em>.</p><pre><code class="language-java">public void sortArray(int[] array) {
        int n = array.length;
        for (int i = 0; i &lt; n-1; i++) {
            for (int j = 0; j &lt; n-i-1; j++) {
                if (array[j] &gt; array[j+1]) {
                    int temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
        }
    }</code></pre><p>Para escrever o teste para isso, seguiremos um procedimento semelhante: chamaremos o método e passaremos um array para ele. Usaremos o <code>assertArrayEquals()</code> para escrever nossa afirmação.</p><pre><code class="language-java">@Test
@DisplayName("Array classificado")
public void sortArray() {
    Basics basicTests = new Basics();
    int[] array = {5, 8, 3, 9, 1, 6};
    basicTests.sortArray(array);
    Assertions.assertArrayEquals(new int[]{1, 3, 5, 6, 8, 9}, array);
}</code></pre><p>Um desafio para você: escreva um código que inverta uma <em>string</em> e escreva um caso de teste para esse código.</p><h2 id="como-criar-mock-ups-e-stubs-para-testes">Como criar <em>mock-ups</em> e <em>stubs</em> para testes</h2><p>Vimos alguns exemplos básicos de testes unitários onde você fez afirmações simples. No entanto, as funções que você está testando podem conter dependências externas, como classes de modelo e conexões de banco de dados ou de rede.</p><p>Você não deve fazer conexões reais em seus testes, pois seria muito demorado. Nesses casos, você faz um <em>mock-up</em> dessas implementações. Vamos ver alguns exemplos de <em>mock-ups</em>.</p><h3 id="fazendo-mock-up-de-uma-classe">Fazendo <em>mock-up </em>de uma classe</h3><p>Vamos ter uma classe <code>User</code> com as seguintes propriedades:</p><pre><code class="language-java">public class User {
    private String username;
    private String password;
    private String role;
    private List&lt;String&gt; posts;    
}</code></pre><p>Clique em <code>Alt + Insert</code> (ou <code>Cmd + Insert</code> no macOS) para gerar métodos <em>getters</em> e <em>setters</em> para as propriedades acima.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-18-at-8.34.34-PM.png" class="kg-image" alt="Screenshot-2023-03-18-at-8.34.34-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/07/Screenshot-2023-03-18-at-8.34.34-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/07/Screenshot-2023-03-18-at-8.34.34-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/07/Screenshot-2023-03-18-at-8.34.34-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-18-at-8.34.34-PM.png 1748w" sizes="(min-width: 720px) 720px" width="1748" height="894" loading="lazy"><figcaption>Gerar opções</figcaption></figure><p>Vamos gerar uma nova classe <code>Mocking</code> que use o objeto acima.</p><pre><code class="language-java">public class Mocking {
    User user;

    public void setUser(User user) {
        this.user = user;
    }
}</code></pre><p>Essa classe possui um método que atribui determinadas permissões com base na função do usuário. Ela retorna <code>1</code> se a permissão for atribuída com sucesso. Do contrário, ela retorna <code>-1</code>.</p><pre><code class="language-java">public int assignPermission() {
        if(user.getRole().equals("admin")) {
            String username = user.getUsername();
            System.out.println("Atribuir permissões especiais para o usuário " + username);
            return 1;
        } else {
            System.out.println("Não é possível atribuir permissão");
            return -1;
        }
    }</code></pre><p>Para fins de demonstração, adicionei apenas instruções <code>println()</code>. A implementação real pode envolver a configuração de certas propriedades.</p><p>No arquivo de testes, adicionaremos uma anotação <code>@ExtendWith</code> no topo, pois estamos usando o Mockito. Não mostrei as importações aqui, pois o IntelliJ as faz automaticamente.</p><pre><code>@ExtendWith(MockitoExtension.class)
public class MockingTests {

}</code></pre><p>Então, como escrevemos o teste para o método? Precisaremos fazer um <em>mock-up</em> do objeto <code>User</code>. Você pode fazer isso adicionando uma anotação <code>@Mock</code> ao declarar o objeto.</p><pre><code class="language-java">@Mock
User user;</code></pre><p>Você também pode usar o método <code>mock()</code>, pois é semelhante.</p><pre><code class="language-java">User user = mock(User.class);</code></pre><p>Vamos escrever o método de teste.</p><pre><code class="language-java">@Test
@DisplayName("Permissão atribuída com sucesso")
public void assignPermissions() {
    Mocking mocking = new Mocking();
    Assertions.assertEquals(1, mocking.assignPermission());
}</code></pre><p>Quando você executar o teste, ele lançará uma <code>NullPointerException</code>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-18-at-8.51.26-PM.png" class="kg-image" alt="Screenshot-2023-03-18-at-8.51.26-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/07/Screenshot-2023-03-18-at-8.51.26-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/07/Screenshot-2023-03-18-at-8.51.26-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/07/Screenshot-2023-03-18-at-8.51.26-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w2400/2024/07/Screenshot-2023-03-18-at-8.51.26-PM.png 2400w" sizes="(min-width: 720px) 720px" width="2418" height="584" loading="lazy"><figcaption>Objeto <em>User</em> é <em>null</em></figcaption></figure><p>Isso ocorre porque o objeto do usuário ainda não foi inicializado. O método que você chamou não conseguiu usar o objeto de <em>mock-up</em>. Para isso, você precisará chamar o método <code>setUser</code>.</p><pre><code class="language-java">mocking.setUser(user);</code></pre><p>Agora, o teste fornece o erro abaixo, pois o objeto de <em>mock-up</em> é inicialmente preenchido com valores nulos.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-18-at-8.53.53-PM.png" class="kg-image" alt="Screenshot-2023-03-18-at-8.53.53-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/07/Screenshot-2023-03-18-at-8.53.53-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/07/Screenshot-2023-03-18-at-8.53.53-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/07/Screenshot-2023-03-18-at-8.53.53-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-18-at-8.53.53-PM.png 2106w" sizes="(min-width: 720px) 720px" width="2106" height="600" loading="lazy"><figcaption>Valor de retorno de <code>getRole()</code> é <em>null</em></figcaption></figure><p>Isso significa que você precisa preencher o objeto de <em>mock-up</em> com valores reais? Não, você só precisa que o método <code>getRole()</code> retorne um valor que não seja <em>null</em>. Para isso, usaremos o <strong><em>stubbing</em> de método.</strong></p><pre><code>when(user.getRole()).thenReturn("admin");</code></pre><p>Usar <code>when()...thenReturn()</code> diz ao teste para retornar um valor quando um método for chamado. Você deve fazer o <em>stubbing</em> de métodos apenas para objetos de <em>mock-up</em>.</p><p>Faremos o mesmo para o método <code>getUsername()</code>.</p><pre><code>when(user.getUsername()).thenReturn("kunal");</code></pre><p>Agora, se você executar o teste, ele será aprovado.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-18-at-9.00.21-PM.png" class="kg-image" alt="Screenshot-2023-03-18-at-9.00.21-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/07/Screenshot-2023-03-18-at-9.00.21-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/07/Screenshot-2023-03-18-at-9.00.21-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/07/Screenshot-2023-03-18-at-9.00.21-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w2400/2024/07/Screenshot-2023-03-18-at-9.00.21-PM.png 2400w" sizes="(min-width: 720px) 720px" width="2480" height="478" loading="lazy"><figcaption>Teste aprovado</figcaption></figure><h3 id="exemplo-de-stubbing-de-m-todo">Exemplo de <em>stubbing </em>de método</h3><p>No exemplo acima, eu simplesmente fiz o <em>stubbing</em> dos métodos <em>getter </em>para demonstrar o <em>stubbing </em>de método. Em vez de fazer <em>stubbing </em>dos <em>getters</em>, você pode definir a função e o nome de usuário com um construtor parametrizado ou métodos <em>setter</em>, se eles estiverem disponíveis.</p><pre><code class="language-java">user.setRole("admin");
user.setUsername("kunal");</code></pre><p>O que fazer, contudo, se a classe <code>User</code> tiver um método que retorna todas as publicações (em inglês, <em>posts</em>) contendo uma determinada palavra nelas?</p><pre><code class="language-java">public List&lt;String&gt; getAllPostsContainingWord(String word) {
        List&lt;String&gt; filteredPosts = new ArrayList&lt;&gt;();
        for(String post: posts) {
            if(post.contains(word))
                filteredPosts.add(post);
        }
        return filteredPosts;
    }</code></pre><p>Queremos que esse método retorne todas as publicações contendo a palavra "incrível". Se você chamar a implementação real desse método, pode levar muito tempo, pois o número de publicações pode ser enorme. Além disso, se você estiver fazendo <em>mocking</em> do objeto <code>User</code>, o array de publicações será nulo.</p><p>Nesse caso, você faz um <em>stub </em>do método e o faz retornar a lista que você deseja.</p><pre><code class="language-java">List&lt;String&gt; filteredPosts = new ArrayList&lt;&gt;();
filteredPosts.add("Dia Incrível");
filteredPosts.add("Este lugar é incrível");
when(user.getAllPostsContainingWord("incrível")).thenReturn(filteredPosts);</code></pre><h3 id="stubbing-de-m-todo-em-consultas-de-banco-de-dados"><em>Stubbing </em>de método em consultas de banco de dados</h3><p>Vamos ver como testar métodos que envolvem fazer conexões com banco de dados. Primeiro, crie uma classe <code>ApplicationDao</code> que contenha todos os métodos que executam consultas ao banco de dados.</p><pre><code class="language-java">public class ApplicationDao {  }</code></pre><p>Defina um método que busca o usuário por <code>id</code> e retorna <code>null</code> se o usuário não for encontrado.</p><pre><code class="language-java">public User getUserById(String id) {
    // Fazer consulta ao banco de dados aqui        
}</code></pre><p>Crie outro método para salvar um usuário no banco de dados. Esse método lança uma exceção se o objeto do usuário que você está tentando salvar for <code>null</code>.</p><pre><code class="language-java">public void save(User user) throws Exception {
    // Fazer consulta ao banco de dados aqui
}</code></pre><p>Nossa classe de <em>mock-up</em> usará esses métodos para implementar suas próprias funcionalidades. Implementaremos uma função que atualiza o nome de um usuário.</p><pre><code class="language-java">public int updateUsername(String id, String username) throws Exception{
            ApplicationDao applicationDao = new ApplicationDao();
            User user = applicationDao.getUserById(id);
            if(user!=null)
                user.setUsername(username);
            applicationDao.save(user);
            return 1;
    }</code></pre><p>A implementação do método é bastante simples. Primeiro, obtenha o usuário por <code>id</code>, altere seu nome de usuário e salve o objeto do usuário atualizado. Escreveremos os casos de teste para esse método.</p><p>Existem dois casos que precisamos testar. O primeiro é quando o usuário é atualizado com sucesso. O segundo é quando a atualização falha, ou seja, quando uma exceção é lançada.</p><p>Antes de escrever os testes, crie um <em>mock-up</em> do objeto <code>ApplicationDao</code>, pois não queremos fazer conexões reais com o banco de dados.</p><pre><code class="language-java">@Mock
ApplicationDao applicationDao;</code></pre><p>Vamos escrever nosso primeiro teste.</p><pre><code>@Test
    @DisplayName("Usuário atualizado com sucesso")
    public void updateUsername() throws Exception {
        ...
    }</code></pre><p>Crie um objeto do usuário para testar.</p><pre><code class="language-java">User user = new User();
user.setUsername("kunal");</code></pre><p>Como estamos chamando um método externo, vamos fazer um <em>stub</em> do método para que ele retorne o objeto <code>User</code> acima.</p><pre><code class="language-java">when(applicationDao.getUserById(Mockito.anyString())).thenReturn(user);</code></pre><p>Passe <code>Mockito.anyString()</code> para o método, pois queremos que o <em>stub</em> funcione para qualquer parâmetro de <em>string</em>. Agora, adicione uma afirmação para verificar se o método está funcionando corretamente.</p><pre><code class="language-java">Assertions.assertEquals(1, mocking.updateUsername("3211", "allan"));</code></pre><p>O método retorna 1 em caso de atualização bem-sucedida. O teste, então, é aprovado.</p><p>Agora, vamos testar outro cenário em que o método falha e lança uma exceção. Simule esse cenário fazendo com que o método <code>getUserById()</code> retorne <em>null</em>.</p><pre><code class="language-java">lenient().when(applicationDao.getUserById(Mockito.anyString())).thenReturn(null);</code></pre><p>Esse valor é, então, passado para o método <code>save()</code>, que, por sua vez, lança uma exceção. Em nossa afirmação, usaremos o método <code>assertThrows()</code> para testar se uma exceção foi lançada. Esse método recebe o tipo da exceção e uma expressão <em>lambda</em> como parâmetros.</p><pre><code class="language-java">Assertions.assertThrows(Exception.class, () -&gt; {
            mocking.updateUsername("3412","allan");
        });</code></pre><p>Como a exceção é lançada, nosso teste é aprovado.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-26-at-4.27.07-PM.png" class="kg-image" alt="Screenshot-2023-03-26-at-4.27.07-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/07/Screenshot-2023-03-26-at-4.27.07-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/07/Screenshot-2023-03-26-at-4.27.07-PM.png 732w" sizes="(min-width: 720px) 720px" width="732" height="342" loading="lazy"><figcaption>Testes aprovados</figcaption></figure><p>Você pode encontrar o código completo aqui no <a href="https://github.com/KunalN25/junit-testing-tutorial">GitHub</a>.</p><h2 id="conclus-o">Conclusão</h2><p>Como desenvolvedor, escrever testes unitários para seu código é importante. Isso ajuda você a identificar <em>bugs </em>mais cedo no processo de desenvolvimento.</p><p>Neste artigo, comecei introduzindo o teste unitário e expliquei três conceitos importantes envolvidos no processo de teste. Isso dará a você uma boa base antes de passar para o código.</p><p>Depois disso, mostrei, com exemplos, como você pode testar diferentes cenários usando as mesmas técnicas básicas de teste. Também mostrei como usar classes e métodos <em>mock-ups</em> para testar implementações complexas.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Interfaces em Java explicadas com exemplos ]]>
                </title>
                <description>
                    <![CDATA[ A interface em Java se parece um pouco com as classes, mas tem uma diferença importante: uma interface pode ter somente assinaturas de métodos, campos e métodos padrão. Desde o Java 8, você também pode criar métodos padrão [https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html]  (documentação em inglês). No bloco seguinte, você verá um exemplo ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/interfaces-em-java-explicadas-com-exemplos/</link>
                <guid isPermaLink="false">650ae08cade67a03f81e5979</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Wed, 20 Sep 2023 12:56:49 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/5f9c9ce6740569d1a4ca34c5.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</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>A interface em Java se parece um pouco com as classes, mas tem uma diferença importante: uma <code>interface</code> pode ter <em>somente</em> assinaturas de métodos, campos e métodos padrão. Desde o Java 8, você também pode criar <a href="https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html">métodos padrão</a> (documentação em inglês). No bloco seguinte, você verá um exemplo de interface:</p><pre><code class="language-java">public interface Veiculo {
    public String placa = "";
    public float velMax
    public void iniciar();
    public void parar();
    default void buzinar(){
      System.out.println("Buzinando");
   }
}</code></pre><p>A interface acima contém dois campos, dois métodos e um método padrão. Sozinha, ela não tem uma finalidade específica, mas a interface geralmente é usada em conjunto com as Classes. Como? É simples. você precisa garantir que alguma classe a <code>implemente</code>.</p><pre><code class="language-java">public class Carro implements Veiculo {
    public void iniciar() {
        System.out.println("ligando o motor...");
    }
    public void parar() {
        System.out.println("parando o motor...");
    }
}</code></pre><p>Temos, porém, uma <strong>regra geral</strong>: a Classe deve implementar <strong><strong>todos</strong></strong> os métodos da Interface. Os métodos devem ter <em>exatamente a mesma</em> assinatura (nome, parâmetros e exceções) descrita na interface. No entanto, a classe <em>não</em> precisa declarar os campos, apenas os métodos.</p><h2 id="inst-ncias-de-uma-interface"><strong><strong><strong>Inst</strong>âncias de uma i<strong>nterface</strong></strong></strong></h2><p>Ao criar uma Classe do Java, que <code>implementa</code> uma Interface, a instância do objeto pode ser referenciada como uma instância da interface. Esse conceito é semelhante ao de instanciação por herança.</p><pre><code class="language-java">// seguindo o exemplo anterior

Veiculo tesla = new Carro();

tesla.iniciar(); // ligando o motor...</code></pre><p>Uma interface <strong><strong>não pode</strong></strong> conter um método construtor. Por isso, você <strong><strong>não pode</strong></strong> criar uma instância da própria interface. É preciso criar uma instância de alguma classe que implemente a interface para fazer referência a ela.</p><p>Pense nas interfaces como se elas fossem um formulário de contrato em branco ou um modelo.</p><p>O que é possível fazer com esse recurso? Polimorfismo! Você pode usar apenas interfaces para fazer referência a instâncias de objeto!</p><pre><code class="language-java">class Caminhao implements Veiculo {
    public void iniciar() {
        System.out.println("ligando o motor do caminhão...");
    }
    public void parar() {
        System.out.println("parando o motor do caminhão...");
    }
}

class Iniciador {
    // método estático, pode ser chamado sem instanciar a classe
    public static void iniciarMotor(Veiculo veiculo) {
        veiculo.iniciar();
    }
}

Veiculo tesla = new Carro();
Veiculo tata = new Caminhao();

Iniciador.iniciarMotor(tesla); // ligando o motor...
Iniciador.iniciarMotor(tata); // ligando o motor do caminhão...</code></pre><h2 id="existe-heran-a-m-ltipla"><strong><strong>Existe herança múltipla<strong>?</strong></strong></strong></h2><p>Sim, você pode implementar várias interfaces em uma única classe. Embora na herança dentro das Classes você esteja restrito a herdar apenas uma classe, com as interfaces, você pode herdar várias. Não se esqueça, porém, de implementar <em>todos</em> os métodos de todas as interfaces para não gerar um erro de compilação!</p><pre><code class="language-java">public interface GPS {
    public void obterCoordenadas();
}

public interface Radio {
    public void ligarRadio();
    public void pararRadio();
}

public class Smartphone implements GPS,Radio {
    public void obterCoordenadas() {
        // retorna coordenadas
    }
    public void ligarRadio() {
      // liga o rádio
    }
    public void pararRadio() {
        // desliga o rádio
    }
}</code></pre><h2 id="alguns-recursos-das-interfaces"><strong><strong>Alguns recursos das i<strong>nterfaces</strong></strong></strong></h2><ul><li>É possível colocar variáveis em uma interface, embora não seja algo sensato, pois as Classes não deveriam ficar restritas a ter a mesma variável. Em resumo, evite inserir variáveis nas interfaces!</li><li>Todas as variáveis em uma interface são públicas, mesmo que você não inclua a palavra-chave <code>public</code>.</li><li>Uma interface não pode especificar a implementação de um método. Essa é uma tarefa das classes. Há, contudo, uma exceção recente (veja abaixo).</li><li>Se uma classe implementa diversas interfaces, há a possibilidade de uma sobreposição de métodos. Como o Java não permite que métodos diferentes tenham exatamente a mesma assinatura, isso pode causar problemas. <a href="http://stackoverflow.com/questions/2598009/method-name-collision-in-interface-implementation-java" rel="nofollow">Esta pergunta no Stack Overflow</a> (texto em inglês) fornece mais informações.</li></ul><h2 id="m-todos-padr-o-das-interfaces"><strong><strong>Métodos padrão das in<strong>terface</strong>s</strong></strong></h2><p>Antes do Java 8, não havia como orientar uma interface para que tivesse uma implementação específica de um método. Isso gerava muita confusão e problemas no código caso uma interface fosse mudada de repente.</p><p>Imagine que você escreveu uma biblioteca de código aberto contendo uma interface. Vamos supor que um de seus clientes, por exemplo, desenvolvedores de todas as partes do mundo, a utilizem muito e que estejam felizes com ela. De repente, você precisa atualizar a biblioteca adicionando a ela uma nova definição de método à interface para dar suporte a um novo recurso. Você acaba causando um problema para <em>todas</em> as <em>builds </em>que possuem aquela interface, já que todas as classes que a implementam precisam mudar. Que catástrofe!</p><p>Felizmente, o Java 8 fornece os métodos <code>default</code> (padrão) para as interfaces. Um método <code>default</code> <em>pode </em>conter sua própria implementação <em><em>dire</em>tamente</em> dentro da interface! Assim, se uma classe não implementar um método padrão, o compilador usará a &nbsp;implementação mencionada na interface. Isso é bom, certo? Desse modo, em sua biblioteca, você pode adicionar quantos métodos padrão quiser nas interfaces sem medo de quebrar coisa alguma!</p><pre><code class="language-java">public interface GPS {
    public void obterCoordenadas();
    default public void obterCoordenadasAproximadas() {
        // implementação para retornar coordenadas de fontes aproximadas
        // como o wi-fi e dispositivos móveis
        System.out.println("Obtendo coordenadas aproximadas...");
    }
}

public interface Radio {
    public void ligarRadio();
    public void pararRadio();
}

public class Smartphone implements GPS,Radio {
    public void obterCoordenadas() {
        // retorna coordenadas
    }
    public void ligarRadio() {
      // liga o rádio
    }
    public void pararRadio() {
        // desliga o rádio
    }

    // sem implementação de obterCoordenadasAproximadas()
}

Smartphone motoG = new Smartphone();
motog.obterCoordenadasAproximadas(); // Obtendo coordenadas aproximadas...</code></pre><p><strong>O que acontece, no entanto, se duas <strong>interfaces </strong>têm a mesma assinatura de métodos<strong>?</strong></strong></p><p>Ótima pergunta. Nesse caso, se você não fornecer a implementação na classe, o pobre compilador se confundirá todo e simplesmente causará um erro! É preciso fornecer a implementação do método padrão dentro da classe também. Existe, além disso, uma maneira bem legal de usar <code>super</code> para chamar a implementação que você deseja:</p><pre><code class="language-java">public interface Radio {
    // public void ligarRadio();
    // public void pararRadio();

    default public void proxima() {
        System.out.println("Próxima de Radio");
    }
}

public interface ReprodutorMusical {
    // public void iniciar();
    // public void pausar();
    // public void parar();

    default public void proxima() {
        System.out.println("Próxima de ReprodutorMusical");
    }
}

public class Smartphone implements Radio, MusicPlayer {
    public void proxima() {
        // Imaginando que você queira chamar proxima de ReprodutorMusical
        ReprodutorMusical.super.proxima();
    }
}

Smartphone motoG = new Smartphone();
motoG.proxima(); // Próxima de ReprodutorMusical</code></pre><h2 id="m-todos-est-ticos-nas-interfaces"><strong><strong>Métodos estáticos nas i<strong>nterfaces</strong></strong></strong></h2><p>Outra coisa que surgiu com o Java 8 foi a capacidade de adicionar métodos estáticos às interfaces. Os métodos estáticos nas interfaces são quase idênticos aos métodos estáticos nas classes concretas. A única e grande diferença está no fato de que os métodos <code>static</code> não são herdados nas classes que implementam a interface. Isso quer dizer que é a interface quem é referenciada ao chamar o método estático, não a classe que implementa a interface.</p><pre><code class="language-java">interface ReprodutorMusical {
  public static void comercial(String patrocinador) {
    System.out.println("Agora, aqui vai uma mensagem trazida até você por " + patrocinador);
  }
  
  public void reproduzir();
}


class Smartphone implements ReprodutorMusical {
	public void reproduzir() {
		System.out.println("Reproduzindo no smartphone");
	}
}

class Main {
  public static void main(String[] args) {
    Smartphone motoG = new Smartphone();
    ReprodutorMusical.comercial("Motorola"); // Chamada a partir da interface, não da classe que a implementa
    // motoG.comercial("Motorola"); // Isso causaria um erro de compilação
  }
}</code></pre><h2 id="herdando-uma-interface"><strong><strong>Herdando uma i<strong>nterface</strong></strong></strong></h2><p>Também é possível, em Java, que uma interface <em>herde</em> outra interface usando a palavra-chave <code>extends</code>:</p><pre><code class="language-java">public interface Reprodutor {
    public void iniciar();
    public void pausar();
    public void parar();
}

public interface ReprodutorMusical extends Reprodutor {
    default public void proxima() {
        System.out.println("Próxima de ReprodutorMusical");
    }
}</code></pre><p>Isso significa que a classe que implementa a interface <code>ReprodutorMusical</code> precisa implementar <em>todos </em>os métodos de <code>ReprodutorMusical</code>, assim como de <code>Reprodutor</code>:</p><pre><code class="language-java">public class SmartPhone implements ReprodutorMusical {
    public void iniciar() {
        System.out.println("iniciar");
    }
    public void parar() {
        System.out.println("parar");
    }
    public void pausar() {
        System.out.println("pausar");
    }
}</code></pre><p>Agora, você já tem um bom entendimento das interfaces em Java! Siga aprendendo, descubra mais sobre as classes abstratas e veja como o Java oferece a você mais uma maneira de definir contratos.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Coletor de lixo em Java – o que é coleta de lixo e como ela funciona na JVM ]]>
                </title>
                <description>
                    <![CDATA[ Em um artigo anterior [https://www.freecodecamp.org/news/jvm-tutorial-java-virtual-machine-architecture-explained-for-beginners/]  (em inglês), escrevi sobre a Máquina Virtual do Java (JVM) e expliquei sua arquitetura. Como parte do componente de ferramenta de execução, eu também falei brevemente sobre o Coletor de Lixo do Java (em inglês, Garbage Collector, ou GC ). Neste artigo, você vai ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/coletor-de-lixo-em-java-o-que-e-a-coleta-de-lixo-e-como-ela-funciona-na-jvm/</link>
                <guid isPermaLink="false">6475361826662f059b14ab97</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Nathalia Nóbrega ]]>
                </dc:creator>
                <pubDate>Wed, 21 Jun 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/GC.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</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>Em um <a href="https://www.freecodecamp.org/news/jvm-tutorial-java-virtual-machine-architecture-explained-for-beginners/">artigo anterior</a> (em inglês), escrevi sobre a Máquina Virtual do Java (JVM) e expliquei sua arquitetura. Como parte do componente de ferramenta de execução, eu também falei brevemente sobre o Coletor de Lixo do Java (em inglês, <em>Garbage Collector, ou GC</em>).</p><p>Neste artigo, você vai aprender mais sobre o <em>Garbage Collector</em>, como ele funciona, os tipos variados de GC presentes no Java e suas vantagens. Também comentarei alguns dos novos Coletores de Lixo experimentais que estão disponíveis nas últimas versões do Java.</p><h2 id="o-que-a-coleta-de-lixo-em-java"><strong>O que é a coleta de lixo em Java?</strong></h2><p>A coleta de lixo é o processo de recolher a memória não utilizada em tempo de execução, destruindo os objetos inutilizados.</p><p>Em linguagens como C e C++, o programador é responsável tanto pela criação quanto pela destruição dos objetos. Às vezes, o programador pode esquecer de destruir objetos que não estão sendo utilizados. A memória alocada para eles, por isso, não é liberada. A memória utilizada pelo sistema continua crescendo e, em algum momento, não haverá memória disponível no sistema para alocar seus objetos. O nome dado a tal processo é "<em>memory leak</em>" (vazamento de memória).</p><p>Após um certo ponto, a memória suficiente não se encontra disponível para a criação de objetos. O programa inteiro, então, finaliza anormalmente devido a um erro do tipo <em>OutOfMemoryError</em>.</p><p>Você pode usar métodos como free() em C e delete() em C++ para realizar operações de coleta de lixo. Em Java, porém, a coleta de lixo acontece automaticamente durante o ciclo de vida de um programa. Isso elimina a necessidade de desalocar memória e, portanto, evita vazamentos de memória.</p><p>O <em>Garbage Collector</em> do Java é o processo no qual os programas em Java realizam o gerenciamento automático de memória. Programas em Java são compilados em <em>bytecode</em>, podendo ser executados na Máquina Virtual do Java (<em>Java Virtual Machine</em>).</p><p>Quando estes programas são executados na JVM, objetos são criados na memória <em>heap</em>, que é a porção da memória dedicada ao programa.</p><p>No decorrer do ciclo de vida de uma aplicação em Java, objetos são criados e dispensados. Ao final, alguns objetos não são mais necessários. É possível dizer que, a qualquer ponto, a memória <em>heap</em> consiste em dois tipos de objetos:</p><ul><li><em>Vivos (Live)</em> – estes objetos estão sendo utilizados e referenciados em algum lugar</li><li><em>Mortos (Dead)</em> – estes objetos não estão sendo utilizados ou não estão sendo referenciados em lugar algum.</li></ul><p>O coletor de lixo encontra esses objetos que não estão sendo utilizados e os exclui para salvar memória.</p><h2 id="como-desreferenciar-um-objeto-em-java">Como desreferenciar um objeto em Java</h2><p>O objetivo principal do coletor de lixo é salvar espaço na memória <em>heap </em>por meio da destruição de objetos que não contêm uma referência. Quando não existem referências a um objeto, a JVM pressupõe que o mesmo está morto (dead) e que não é mais necessário. Então, a memória <em>heap </em>ocupada por este objeto pode ser desocupada.</p><p>Existem diversas formas pelas quais as referências de um objeto podem ser desfeitas para transformá-lo em um candidato à coleta de lixo. Algumas delas são:</p><h3 id="transformar-uma-refer-ncia-em-nula">Transformar uma referência em nula</h3><pre><code class="language-java">Estudante estudante = new Estudante();
estudante = null;</code></pre><h3 id="atribuir-uma-refer-ncia-outra">Atribuir uma referência à outra</h3><pre><code class="language-java">Estudante estudanteUm = new Estudante();
Estudante estudanteDois = new Estudante();
estudanteUm = estudanteDois; // agora o primeiro objeto referenciado por estudanteUm está disponível para garbage collection</code></pre><h3 id="utilizar-um-objeto-an-nimo">Utilizar um objeto anônimo</h3><pre><code class="language-java">registrar(new Estudante());</code></pre><h2 id="como-funciona-o-garbage-collection-em-java">Como funciona o Garbage Collection em Java?</h2><p>O Garbage Collection do Java é um processo automático. O programador não precisa marcar explicitamente os objetos a serem excluídos.</p><p>A implementação da coleta de lixo se encontra na JVM (Máquina Virtual do Java). Cada JVM pode implementar sua própria versão de <em>Garbage Collection</em>. Porém, essa versão deve atender aos padrões da especificação da JVM de trabalhar com objetos presentes na memória <em>heap</em>, marcar ou identificar os objetos inalcançáveis, e destruí-los com compactação.</p><h2 id="o-que-s-o-as-roots-de-garbage-collection-em-java">O que são as <em>roots</em> de Garbage Collection em Java?</h2><p>Coletores de lixo funcionam sob o conceito de <em>Garbage Collection Roots</em> (GC Roots) para identificar objetos vivos e mortos.</p><p>Exemplos dessas <em>roots </em>de <em>Garbage Collection</em> são:</p><ul><li>Classes executadas pelo executor de classes do sistema (com exceção dos executores de classes customizadas)</li><li>Threads ativas</li><li>Variáveis locais e parâmetros dos métodos em execução</li><li>Variáveis locais e parâmetros de métodos JNI (<em>Java Native Interface</em>)</li><li>Referências globais de JNI</li><li>Objetos utilizados como monitores para sincronização</li><li>Objetos mantidos da coleta de lixo pela JVM para seus fins</li></ul><p>O coletor de lixo percorre todo o grafo de objetos na memória, começando pelas <em>roots </em>de <em>Garbage Collection</em> e referências posteriores às <em>roots</em> de outros objetos.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-76.png" class="kg-image" alt="image-76" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/06/image-76.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/06/image-76.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-76.png 1372w" sizes="(min-width: 720px) 720px" width="1372" height="1183" loading="lazy"></figure><h2 id="etapas-de-coleta-de-lixo-em-java">Etapas de coleta de lixo em Java</h2><p>Uma implementação padrão de coletor de lixo envolve três etapas:</p><h3 id="marcar-objetos-como-vivos">Marcar objetos como vivos</h3><p>Nessa etapa, o GC identifica todos os objetos vivos na memória ao percorrer o grafo de objetos.</p><p>Quando o GC "visita" um objeto, o marca como acessível – logo, ele está vivo. Todo objeto que o GC visita é marcado como vivo. Todos os objetos que não podem ser visitados pelas <em>roots </em>do GC são lixo e considerados como candidatos para coleta.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-82.png" class="kg-image" alt="image-82" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/06/image-82.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/06/image-82.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/06/image-82.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-82.png 1613w" sizes="(min-width: 720px) 720px" width="1613" height="294" loading="lazy"></figure><h3 id="se-livrar-de-objetos-mortos">Se livrar de objetos mortos</h3><p>Após a fase de marcação, temos um espaço na memória que é ocupado tanto por objetos vivos (<em>visited</em>), quanto por objetos mortos (<em>unvisited</em>). A fase de "livração" libera fragmentos de memória que contêm objetos mortos.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-83.png" class="kg-image" alt="image-83" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/06/image-83.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/06/image-83.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/06/image-83.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-83.png 1613w" sizes="(min-width: 720px) 720px" width="1613" height="294" loading="lazy"></figure><h3 id="compactar-os-objetos-restantes-na-mem-ria">Compactar os objetos restantes na memória</h3><p>Os objetos mortos que são removidos durante a fase de liberação não precisam necessariamente estar um ao lado do outro. Portanto, você pode acabar tendo espaços de memória fragmentados.</p><p>A memória, então, pode ser compactada depois que o coletor de lixo excluir os objetos mortos, para que os objetos remanescentes estejam em um bloco contíguo no começo da memória <em>heap</em>.</p><p>O processo de compactação faz com que seja mais fácil alocar memória para novos objetos de forma sequencial.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-85.png" class="kg-image" alt="image-85" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/06/image-85.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/06/image-85.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/06/image-85.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-85.png 1613w" sizes="(min-width: 720px) 720px" width="1613" height="294" loading="lazy"></figure><h2 id="o-que-a-coleta-de-lixo-geracional-em-java">O que é a coleta de lixo geracional em Java?</h2><p>Os coletores de lixo em Java implementam uma estratégia chamada coleta de lixo geracional, que categoriza objetos por idade.</p><p>Ter que marcar e compactar todos os objetos em uma JVM é ineficiente. Quanto mais e mais objetos são alocados, a lista de objetos cresce, levando a um tempo de coleta mais longo. A análise empírica de aplicações têm mostrado que a maioria dos objetos em Java têm vida curta.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/ObjectLifetime.gif" class="kg-image" alt="ObjectLifetime" width="742" height="513" loading="lazy"><figcaption>Fonte: oracle.com</figcaption></figure><p>No exemplo acima, o eixo Y representa o número de bytes alocados. O eixo X representa o tempo. Como você pode ver, menos e menos objetos permanecem alocados com o passar do tempo.</p><p>Na verdade, a maioria dos objetos têm uma vida muito curta, como foi demonstrado pelos altos valores no lado esquerdo do gráfico. É por isso que o Java categoriza e realiza coleta de lixo de acordo com as gerações de objetos.</p><p>A área da memória <em>heap </em>na JVM é dividida em três seções:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-70.png" class="kg-image" alt="image-70" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/06/image-70.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/06/image-70.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/06/image-70.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w2400/2023/06/image-70.png 2400w" sizes="(min-width: 1200px) 1200px" width="2860" height="987" loading="lazy"></figure><h2 id="gera-o-jovem">Geração jovem</h2><p>Objetos recentemente criados começam na geração jovem (<em>Young Generation</em>). Esta geração é subdividida em:</p><ul><li><strong>Espaço Éden</strong> (EdenSpace) – todos os novos objetos começam aqui, e a memória inicial é alocada neles.</li><li><strong>Espaço de sobreviventes</strong> (FromSpace e ToSpace) – objetos são movidos daqui para o Éden após um ciclo de coleta.</li></ul><p>Quando objetos são coletados a partir da Geração Jovem, é um <em>evento menor de coleta de lixo.</em></p><p>Quando o Espaço Éden é preenchido por objetos, um evento menor de Garbage Collection é realizado. Todos os objetos mortos são excluídos e todos os objetos vivos são movidos para um dos Espaços de sobreviventes. &nbsp;Coletas de lixo menores também verificam os objetos em um espaço de sobreviventes e os movem para outro espaço.</p><p>Tenha a seguinte sequência como exemplo:</p><ol><li>O Éden tem todos os objetos (vivos e mortos)</li><li>Uma Coleta de Lixo menor ocorre – todos os objetos mortos são removidos do Éden. Todos os objetos vivos são movidos para o S1 (FromSpace). O Éden e o S2 agora estão vazios.</li><li>Objetos são criados e adicionados ao Éden. Alguns objetos neste espaço e no S1 se tornam mortos.</li><li>Outro evento menor de GC ocorre – todos os objetos mortos são removidos do Éden e do S1. Todos os objetos vivos são movidos para o S2 (ToSpace). Eden e S1 agora estão vazios.</li></ol><p>Portanto, em qualquer momento, um dos espaços de sobreviventes está vazio. Quando os objetos sobreviventes alcançam uma certa "experiência" em serem movidos entre os espaços de sobreviventes diversas vezes, eles são transferidos à Geração Velha.</p><p>Você pode usar a flag `-Xmn` para definir o tamanho da Geração Jovem.</p><h2 id="gera-o-velha">Geração velha</h2><p>Objetos que são mais velhos são eventualmente movidos da Geração Jovem para a Geração Velha (<em>Old Generation</em>). Esta geração também é referenciada como <em>Tenured Generation</em>, e contêm objetos que continuaram nos espaços de sobreviventes por um longo tempo.</p><p>Há um limite definido para a promoção de um objeto que decide quantos ciclos de coleta de lixo ele pode sobreviver antes de ser movido para a Geração Antiga.</p><p>Quando objetos são coletados da Geração Antiga, chamamos de evento maior de coleta de lixo.</p><p>Você pode usar as <em>flags </em><code>-Xms</code> e <code>-Xmx</code> para determinar o tamanho inicial e máximo da memória <em>heap</em>.</p><p>Já que o Java utiliza coleta de lixo geracional, quanto mais eventos de coleta um objeto sobrevive, mais ele é promovido na <em>heap</em>. Ele começa na Geração Jovem e eventualmente termina na <em>Tenured Generation</em> se conseguir sobreviver por tempo suficiente.</p><p>Considere o seguinte exemplo para entender a promoção de objetos entre espaços e gerações:</p><p>Quando um objeto é criado, ele primeiro fica alocado no <strong>Espaço Éden</strong> da <strong>Geração Jovem</strong>. Quando um evento menor de coleta de lixo ocorre, os objetos vivos são promovidos ao <strong>FromSpace</strong>. Quando um novo evento menor ocorre, tanto os objetos vivos do <strong>Éden</strong> e do <strong>FromSpace</strong> são movidos para o <strong>ToSpace</strong>.</p><p>Este ciclo continua por um número específico de vezes. Se o objeto continuar sendo referenciado até esse ponto, o próximo ciclo de coleta de &nbsp;lixo vai movê-lo para o espaço da Geração Antiga.</p><h2 id="gera-o-permanente">Geração permanente</h2><p>Metadados de classes e métodos são alocados na Geração Permanente (<em>Permanent Generation</em>). Ela é utilizada pela JVM durante o tempo de execução com base nas classes em uso pela aplicação. Classes que não estão mais em uso nesta Geração podem ser coletadas pelo <em>Garbage Collector</em>.</p><p>Você pode usar as flags <code>-XX:PermGen</code> e <code>-XX:MaxPermGen</code> para determinar o tamanho inicial e máximo da <em>Permanent Generation</em>.</p><h2 id="metaspace">MetaSpace</h2><p>A partir do Java 8, o espaço de memória <strong>MetaSpace</strong> substituiu o espaço <strong>PermGen</strong>. A implementação difere da PermGen, e este espaço da Heap agora é redimensionado automaticamente.</p><p>Isso evita o problema de aplicações ficarem sem memória devido ao tamanho limite do espaço PermGen da memória <em>Heap</em>. A memória <em>MetaSpace</em> pode ser coletada e as classes que não estão mais em uso podem ser automaticamente coletadas quando o MetaSpace alcança seu tamanho limite.</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.49999999999999%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="113" src="https://www.youtube.com/embed/X1DkoRGVRp4?start=1&amp;feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" title="Garbage Collection in Java | What is GC and How it Works in JAVA | Part One" name="fitvid0"></iframe>
          </div>
        </div>
      </figure><h2 id="tipos-de-garbage-collector-na-m-quina-virtual-do-java">Tipos de Garbage Collector na Máquina Virtual do Java</h2><p>A coleta de lixo faz com que o Java seja uma linguagem eficiente no quesito de uso de memória porque remove os objetos sem referência da memória <em>heap </em>e libera espaço para novos objetos.</p><p>A Máquina Virtual do Java tem oito tipos de coletores de lixo. Vamos conhecer cada um deles com mais detalhe.</p><h2 id="gc-serial">GC serial</h2><p>Esta é a implementação mais simples do <em>Garbage Collector </em>e foi feita para aplicações pequenas que estão sendo executadas em ambientes <em>single-threaded</em>. Todos os eventos de coleta de lixo são conduzidos em série em uma <em>thread</em>. A compactação da memória é executada após cada coleta.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-68.png" class="kg-image" alt="image-68" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/06/image-68.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/06/image-68.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/06/image-68.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-68.png 1686w" sizes="(min-width: 720px) 720px" width="1686" height="647" loading="lazy"></figure><p>Quando a aplicação é executada, ocorre um evento "<em>stop the world</em>" (pare o mundo) onde toda a aplicação é pausada. Já que a aplicação inteira é congelada durante a coleta de lixo, o GC serial não é recomendado em aplicações de larga escala, onde a latência baixa é uma necessidade.</p><p>O argumento da JVM para utilizar o Garbage Collector serial é <code>-XX:+UeSerialGC</code>.</p><h2 id="gc-paralelo">GC paralelo</h2><p>O coletor paralelo é feito para aplicações com conjuntos de dados de médio a largo porte que rodam em multiprocessadores ou hardware <em>multi-threaded</em>. Essa é a implementação padrão do <em>Garbage Collector</em> da JVM e também é conhecida como <em>Throughput Collector</em>.</p><p>Múltiplas <em>threads </em>são utilizadas para um evento menor de coleta de lixo na Geração Jovem. Uma única <em>thread </em>é utilizada para eventos maiores de coleta na Geração Velha.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-66.png" class="kg-image" alt="image-66" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/06/image-66.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/06/image-66.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/06/image-66.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-66.png 1686w" sizes="(min-width: 720px) 720px" width="1686" height="647" loading="lazy"></figure><p>Executar o GC paralelo também ocasiona o evento "<em>stop the world</em>" e a aplicação é pausada. Já que esta implementação é mais apropriada em um ambiente <em>multi-threaded</em>, ela pode ser usada quando muitas atividades são feitas e pausas longas são aceitáveis, como, por exemplo, executar uma tarefa em lote.</p><p>O argumento na JVM para executar o GC paralelo é <code>-XX:+UseParallelGC</code>.</p><h2 id="gc-paralelo-antigo">GC paralelo antigo</h2><p>Essa é a versão padrão do GC paralelo desde o Java 7u4. É a mesma implementação do GC paralelo, exceto pelo fato de utilizar <em>threads </em>múltiplas tanto para a Geração Jovem quanto para a Velha.</p><p>O argumento na JVM para executar o <em>Garbage Collector </em>paralelo antigo é <code>-XX:+UseParallelOldGC</code>.</p><h2 id="gc-cms-concurrent-mark-sweep-">GC CMS (Concurrent Mark Sweep)</h2><p>Essa implementação também é conhecida como o coletor de pausa baixa simultânea. Múltiplas <em>threads </em>são usadas como coletas de lixo menores usando o mesmo algoritmo do paralelo. Coletas de lixo maiores são <em>multi-threaded</em>, como no GC paralelo antigo, mas o CSM roda de forma simultânea aos processos da aplicação para minimizar os eventos "<em>stop the world</em>".</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-67.png" class="kg-image" alt="image-67" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/06/image-67.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/06/image-67.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/06/image-67.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-67.png 1686w" sizes="(min-width: 720px) 720px" width="1686" height="647" loading="lazy"></figure><p>Por causa disso, o coletor CSM usa mais CPU do que as outras implementações de GC. Se você pode alocar mais CPU em prol de melhor desempenho, o CMS é uma escolha melhor que o paralelo. Não há compactação nesta implementação.</p><p>O argumento na JVM para usar o <em>Garbage Collector</em> de <em>Concurrent Mark Sweep</em> (em português, algo como "varredura de marca concorrente") é <code>-XX:+UseConcMarkSweepGC</code>.</p><h2 id="gc-g1-garbage-first-">GC G1 (Garbage First)</h2><p>O G1GC tinha a intenção de substituir o CMS e foi criado para aplicações <em>multi-threaded</em> que possuem um tamanho grande de memória <em>heap </em>disponível (acima de 4GB). É implementado de modo paralelo e simultânea, como o CMS, mas funciona de maneira um pouco diferente debaixo dos panos em comparação com os <em>garbage collectors </em>anteriores.</p><p>Apesar do G1 também ser geracional, ele não separa espaços para as gerações Jovem e Velha. Na verdade, cada geração é um conjunto de espaços, o que permite alterar o tamanho da Geração Jovem de modo flexível.</p><p>Ele particiona a <em>heap </em>em um conjunto de espaços de tamanhos iguais (1MB a 32MB - dependendo do tamanho da <em>heap</em>) e utiliza múltiplas <em>threads </em>para as escanear. Uma região pode ser Velha ou Jovem em qualquer período de tempo durante a execução do programa.</p><p>Após o período de marcação ser completo, o G1 sabe quais espaços contêm mais objetos que precisam ser coletados. Se o usuário está interessado em tempos de pausa mínimos, o G1 pode escolher evacuar apenas alguns espaços. Se o usuário não se preocupa com isso ou definiu um tempo de pausa grande, o G1 pode escolher incluir mais espaços.</p><p>Já que o G1CC identifica os espaços com a maior quantidade de lixo e realiza a coleta naqueles espaços primeiro, ele é chamado de Garbage First (lixo primeiro).</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-88.png" class="kg-image" alt="image-88" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/06/image-88.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/06/image-88.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/06/image-88.png 1445w" sizes="(min-width: 720px) 720px" width="1445" height="985" loading="lazy"></figure><p>Além dos espaços de memória Eden, Sobreviventes e Velho, existem mais dois tipos de espaços presentes no G1CC:</p><ul><li><em>Humongous (Enorme) – usado para objetos grandes (maiores que 50% do tamanho da </em>heap<em>)</em></li><li><em>Available (Disponíveis) – usado para espaços não utilizados ou não alocados.</em></li></ul><p>O argumento na JVM para usar o <em>Garbage Collector</em> G1 é <code>-XX:+UseG1GC</code> .</p><h2 id="garbage-collector-epsilon">Garbage Collector Epsilon</h2><p>O Epsilon é um coletor de lixo "do-nothing" (que "não faz nada") que foi lançado como parte da JDK 11. Ele gerencia a alocação de memória, mas não implementa nenhum mecanismo de aproveitamento de memória. Uma vez que a memória <em>heap </em>disponível está cheia, a JVM para de funcionar.</p><p>Ele pode ser usado para aplicações que são sensíveis a latências extremas, onde os desenvolvedores sabem o <em>footprint</em> exato da memória da aplicação, ou até mesmo possuem aplicações que são (quase) <em>garbage-free</em> (livres de lixo). A utilização do GC Epsilon em qualquer outro cenário é desencorajado.</p><p>O argumento na JVM para utilizar o <em>Garbage Collector</em> Epsilon é <code>-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC</code>.</p><h2 id="shenandoah">Shenandoah</h2><p>O Shenandoah é um GC novo que foi lançado como parte do JDK 12. A sua vantagem principal sobre o <em>Garbage Collector</em> G1 é que ele realiza mais ciclos de coleta de lixo de maneira simultânea às <em>threads </em>da aplicação. O G1 pode evacuar seus espaços na <em>heap </em>apenas quando a aplicação é pausada, enquanto o Shenandoah pode realocar objetos simultaneamente com a aplicação.</p><p>Shenandoah pode compactar objetos vivos, coletar o lixo e mandar RAM de volta ao sistema operacional quase imediatamente após detectar memória livre. Já que tudo isso ocorre simultaneamente enquanto a aplicação roda, o Shenandoah é mais intensivo no quesito do uso de CPU.</p><p>O argumento na JVM para utilizar o <em>Garbage Collector</em> Shenandoah é <code>-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC</code>.</p><h2 id="zgc">ZGC</h2><p>O ZGC é outro <em>Garbage Collector</em> que foi lançado como parte da JDK 11 e foi melhorado na JDK 12. Ele foi criado para aplicações que requerem baixa latência (pausas de menos de 10ms) e/ou que utilizam um grande espaço da memória <em>heap</em> (multi-terabytes).</p><p>Os principais objetivos do ZGC são a baixa latência, escalabilidade e facilidade de uso. Para alcançar isso, o ZGC permite que uma aplicação em Java continue rodando enquanto ele executa todas as operações de <em>Garbage Collection</em>. Por padrão, o ZGC libera a memória não utilizada e a retorna ao sistema operacional.</p><p>Logo, o ZGC traz uma melhora significativa sobre outros <em>Garbage Collectors</em> tradicionais ao prover tempos de pausa extremamente baixos (tipicamente dentro de 2ms).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/figure2_600w.jpg" class="kg-image" alt="figure2_600w" srcset="https://www.freecodecamp.org/portuguese/news/content/images/2023/06/figure2_600w.jpg 600w" width="600" height="525" loading="lazy"><figcaption>Fonte: oracle.com</figcaption></figure><p>O argumento na JVM para utilizar o <em>Garbage Collector </em>Shenandoah é <code>-XX:+UnlockExperimentalVMOptions -XX:+UseZGC</code>.</p><p><strong>Observação:</strong> tanto o Shanandoah quanto o ZGC estão sob planos de passarem a ser <em>features </em>de produção e serem removidos do estágio de experimentação na JDK 15.</p><h2 id="como-escolher-o-garbage-collector-certo">Como escolher o <em>Garbage Collector </em>certo?</h2><p>Se a sua aplicação não tem tempos de pausa estritos, você deve somente rodar a sua aplicação e deixar a JVM escolher o coletor certo para você.</p><p>Na maior parte do tempo, as configurações padrão devem funcionar bem. Se necessário, você pode ajustar o tamanho da <em>heap </em>para melhorar o desempenho. Se o desempenho ainda não alcançar suas expectativas, você pode alterar o coletor de lixo padrão de acordo com as necessidades do seu projeto:</p><ul><li><strong>Serial</strong> – se a aplicação tem um conjunto de dados pequeno (aproximadamente 100MB) e/ou vai rodar em um único processador sem ter requisitos de tempo de pausa.</li><li><strong>Paralelo</strong> – se o melhor desempenho da aplicação for a prioridade e não houver requisitos para tempos de pausa ou pausas de um segundo ou mais serão aceitáveis.</li><li><strong>CMS/G1</strong> – se o tempo de resposta é mais importante que a taxa de processamento e as pausas de coleta de lixo devem ser mantidas abaixo de aproximadamente um segundo.</li><li><strong>ZGC</strong> – se o tempo de resposta for a prioridade maior, e/ou você está usando grande parte da <em>heap</em>.</li></ul><h2 id="vantagens-do-garbage-collection">Vantagens do <em>Garbage Collection</em></h2><p>Existem múltiplos benefícios da coleta de lixo em Java.</p><p>Primeiramente, ela deixa o seu código mais simples. Você não precisa se preocupar com a alocação correta de memória e ciclos de liberação. Você para de usar um objeto no seu código e a memória que ele utiliza vai ser automaticamente liberada em algum momento.</p><p>Programadores que trabalham em linguagens sem <em>Garbage Collection </em>(como C e C++) devem implementar gerenciamento de memória manual em seus códigos.</p><p>Este processo também faz com que o Java seja eficiente em termos de memória, pois o coletor de lixo remove os objetos não referenciados da memória <em>heap</em>. Isso libera espaço na <em>heap </em>para acomodar novos objetos.</p><p>Enquanto alguns programadores argumentam em favor do gerenciamento de memória manual ao invés de <em>Garbage Collection</em>, o GC é agora um componente padrão em diversas linguagens de programação populares.</p><p>Para cenários onde o <em>Garbage Collector</em> impacta negativamente o desempenho, o Java oferece diversas opções para melhorar sua eficiência.</p><h2 id="melhores-pr-ticas-de-garbage-collection">Melhores práticas de <em>Garbage Collection</em></h2><h3 id="evite-disparos-manuais">Evite disparos manuais</h3><p>Além dos mecanismos básicos de coleta de lixo, um dos pontos mais importantes para entender a respeito de <em>Garbage Collection </em>no Java é que ele não é determinístico. Isso significa que não tem como prever quando a coleta de lixo vai ocorrer durante o tempo de execução.</p><p>É possível incluir uma sugestão à JVM no seu código para que ela inicie o coletor de lixo com os métodos <code>System.gc()</code> ou <code>Runtime.gc()</code>, mas isso não dá garantia de que o coletor realmente vai ser executado.</p><h3 id="utilize-ferramentas-de-an-lise">Utilize ferramentas de análise</h3><p>Se você não tem memória suficiente para rodar sua aplicação, você vai lidar com problemas de lentidão, um longo período de coleta de lixo, eventos "<em>stop the world</em>" e, por fim, erros do tipo <em>out of memory.</em> Isso pode indicar que o tamanho da sua <em>heap </em>é muito pequeno, mas também que você pode ter um vazamento de memória na sua aplicação.</p><p>Você pode ter o auxílio de uma ferramenta de monitoramento como o <code>jstat</code> ou <em>Java Flight Recorder</em> para analisar se o uso da memória <em>heap </em>cresce indefinidamente, o que pode indicar um bug no seu código.</p><h3 id="configura-es-padr-o-s-o-suas-amigas">Configurações padrão são suas amigas</h3><p>Se você estiver executando uma aplicação Java pequena e independente, você muito provavelmente não precisa alterar as configurações do <em>Garbage Collector</em>. As configurações padrão devem dar conta do trabalho.</p><h3 id="utilize-flags-na-jvm-para-ajustes">Utilize <em>flags </em>na JVM para ajustes</h3><p>A melhor forma de ajustar a <em>Garbage Collection</em> de acordo com as suas necessidades é utilizando <em>flags </em>na JVM. <em>Flags </em>podem configurar o GC que vai ser utilizado (Serial, G1 ou outros), o tamanho inicial e máximo da memória <em>heap</em>, o tamanho dos espaços da <em>heap </em>(Geração Jovem, Velha) e muito mais.</p><h3 id="escolha-o-coletor-apropriado">Escolha o coletor apropriado</h3><p>A natureza da aplicação que está passando por ajustes é um guia inicial muito eficiente para as configurações do coletor. Por exemplo, o GC paralelo é eficiente, mas vai causar eventos "<em>stop the world</em>" frequentes, fazendo com que ele seja mais apropriado para processamento em back-end, onde as longas pausas para coleta de lixo são aceitáveis.</p><p>Por outro lado, o Garbage Collector CMS foi criado para minimizar pausas, sendo ideal para aplicações baseadas na Web, onde a responsividade é importante.</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.49999999999999%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="113" src="https://www.youtube.com/embed/4sBhc-pSILs?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" title="Garbage Collection in Java | Types of Garbage Collectors in JAVA | Part Two" name="fitvid1"></iframe>
          </div>
        </div>
      </figure><h2 id="conclus-o">Conclusão</h2><p>Neste artigo, discutimos <em>Garbage Collection</em> em Java, como funciona e seus diferentes tipos.</p><p>Para muitas aplicações simples, <em>Garbage Collection</em> não é algo que um programador Java precise considerar. Contudo, para programadores que querem melhorar suas habilidades em Java, é importante entender como esse processo funciona.</p><p>Este conceito também é muito popular em entrevistas técnicas, tanto para cargos de back-end júnior, quanto sênior.</p><p>Agradecemos por sua companhia até aqui. Esperamos que tenha gostado do artigo. Você pode se conectar com o autor pelo <a href="https://www.linkedin.com/in/theawesomenayak/">LinkedIn</a>, onde ele fala regularmente sobre assuntos como tecnologia e a vida. Dê uma olhada também em <a href="https://www.freecodecamp.org/news/author/theawesomenayak/">outros artigos do autor</a> (em inglês) e no <a href="https://www.youtube.com/channel/UCmWAaPgfWAkl-Jep5mY-NNg?sub_confirmation=1">canal do autor no YouTube</a>. Boa leitura. 🙂️</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Filas de prioridades em Java explicadas e com exemplos ]]>
                </title>
                <description>
                    <![CDATA[ Filas de prioridades geralmente são usadas em aplicações da vida real. Neste artigo, aprenderemos o que são essas filas e como podemos usá-las em Java. Antes de discutirmos o que é uma fila de prioridades, vejamos o que é uma fila regular. Uma fila (ou, em inglês, queue) regular segue ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/filas-de-prioridades-em-java-explicadas-e-com-exemplos/</link>
                <guid isPermaLink="false">63b0372544e27f060d7a51ad</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Thu, 05 Jan 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/12/5f9c99d7740569d1a4ca21ff.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/priority-queue-implementation-in-java/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Priority Queues in Java Explained with Examples</a>
      </p><p>Filas de prioridades geralmente são usadas em aplicações da vida real. Neste artigo, aprenderemos o que são essas filas e como podemos usá-las em Java.</p><p>Antes de discutirmos o que é uma fila de prioridades, vejamos o que é uma fila regular.</p><p>Uma fila (ou, em inglês, <em>queue</em>) regular segue a estrutura em que o primeiro a entrar é o primeiro a sair (em inglês, <em>first in first out</em>, também conhecida pela abreviação <em>FIFO</em>). Isso significa que, se 3 mensagens – m1, m2 e m3 – entrarem na fila nessa ordem, elas sairão da fila exatamente na mesma ordem.</p><h2 id="por-que-precisamos-de-filas"><strong>Por que precisamos de filas?</strong></h2><p>Vamos supor que tenhamos produtores de dados (por exemplo, quando um usuário clica em uma página da web) que são extremamente rápidos. Queremos, no entanto, consumir esses dados em um ritmo mais lento posteriormente.</p><p>Nesse caso, o produtor dos dados enviaria todas as mensagens para a fila e o consumidor as receberia mais tarde, vindas da fila, em um ritmo mais lento.</p><h2 id="o-que-uma-fila-de-prioridades"><strong>O que é uma fila de prioridades?</strong></h2><p>Como mencionamos anteriormente, uma fila regular segue a estrutura em que o primeiro a entrar é o primeiro a sair. Em alguns cenários, contudo, queremos processar as mensagens de uma fila com base em sua prioridade, não na ordem em que entraram na fila.</p><p>As filas de prioridades ajudam a consumir as mensagens de prioridade mais alta primeiro, seguidas daquelas com prioridade mais baixa.</p><h2 id="filas-de-prioridades-em-java"><strong>Filas de prioridades em Java</strong></h2><p>Vamos agora ver um código real em Java que nos mostrará como usar filas de prioridades.</p><h3 id="filas-de-prioridades-com-ordenamento-natural"><strong>Filas de prioridades com ordenamento natural</strong></h3><p>Aqui vemos um código mostrando como criar uma fila de prioridades simples para strings</p><pre><code class="language-java">private static void testStringsNaturalOrdering() {
        Queue&lt;String&gt; testStringsPQ = new PriorityQueue&lt;&gt;();
        testStringsPQ.add("abcd");
        testStringsPQ.add("1234");
        testStringsPQ.add("23bc");
        testStringsPQ.add("zzxx");
        testStringsPQ.add("abxy");

        System.out.println("Strings armazenadas por ordenamento natural em uma fila de prioridades\n");
        while (!testStringsPQ.isEmpty()) {
            System.out.println(testStringsPQ.poll());
        }
    }</code></pre><p>A primeira linha nos informa que estamos criando uma fila de prioridades:</p><pre><code class="language-java">Queue&lt;String&gt; testStringsPQ = new PriorityQueue&lt;&gt;();</code></pre><p>PriorityQueue está disponível no pacote java.util.</p><p>Em seguida, adicionamos 5 strings em ordem aleatória na fila de prioridades. Para isso, usamos a função <strong><strong>add()</strong></strong>, como vemos abaixo:</p><pre><code class="language-java">testStringsPQ.add("abcd");
testStringsPQ.add("1234");
testStringsPQ.add("23bc");
testStringsPQ.add("zzxx");
testStringsPQ.add("abxy");</code></pre><p>Para obter o item mais recente da fila, usamos a função <strong><strong>poll()</strong></strong>, deste modo:</p><pre><code class="language-java">testStringsPQ.poll()</code></pre><p><strong><strong>poll() </strong></strong>nos dará o item mais recente e o removerá da fila. Se quisermos obter o item mais recente da fila sem removê-lo, podemos usar a função <strong><strong>peek()</strong></strong>:</p><pre><code class="language-java">testStringsPQ.peek()</code></pre><p>Por fim, imprimimos todos os elementos da fila usando a função poll(), assim:</p><pre><code class="language-java">while (!testStringsPQ.isEmpty()) {
   System.out.println(testStringsPQ.poll());
}</code></pre><p>Aqui vemos o resultado do programa acima:</p><pre><code class="language-bash">1234
23bc
abcd
abxy
zzxx</code></pre><p>Como não demos à fila de prioridades uma maneira de priorizar seu conteúdo, foi usado o ordenamento natural padrão. Nesse caso, recebemos os dados na ordem ascendente das strings. Essa não é a mesma ordem na qual os itens foram adicionados à fila.</p><h3 id="como-conseguir-um-ordenamento-personalizado"><strong>Como conseguir um ordenamento personalizado?</strong></h3><p>Isso também é possível. Conseguimos fazer isso com a ajuda de um <strong><strong>compara</strong>d<strong>or</strong></strong> (em inglês, <em>comparator</em>).</p><p>Vamos criar agora uma fila de prioridades de números inteiros. Desta vez, no entanto, vamos obter o resultado em ordem descendente de valores.</p><p>Para conseguir isso, primeiro precisamos criar um <em>comparator</em> de número inteiros:</p><pre><code class="language-java"> static class CustomIntegerComparator implements Comparator&lt;Integer&gt; {

        @Override
        public int compare(Integer o1, Integer o2) {
            return o1 &lt; o2 ? 1 : -1;
        }
    }</code></pre><p>Para criar um <em>comparator</em>, implementamos a interface <strong><strong>comparator</strong></strong> e sobrescreveremos o método <strong><strong>compare</strong></strong>.</p><p>Usando <strong><strong>o1 &lt; o2 ? 1 : -1</strong></strong>,<strong> </strong>obteremos o resultado em ordem descendente. Se tivéssemos usado <strong><strong>o1 &gt; o2 ? 1 : -1, </strong></strong>obteríamos o resultado em ordem ascendente.</p><p>Agora que já temos o <em>comparator</em>, precisamos adicioná-lo à fila de prioridades. Podemos fazer isso da seguinte maneira:</p><pre><code class="language-java">Queue&lt;Integer&gt; testIntegersPQ = new PriorityQueue&lt;&gt;(new CustomIntegerComparator());</code></pre><p>Aqui vemos o resto do código que adicionará elementos à fila de prioridades e os mostrará na tela:</p><pre><code class="language-java">   testIntegersPQ.add(11);
        testIntegersPQ.add(5);
        testIntegersPQ.add(-1);
        testIntegersPQ.add(12);
        testIntegersPQ.add(6);

        System.out.println("Números inteiros armazenados em ordem inversa na fila de prioridades\n");
        while (!testIntegersPQ.isEmpty()) {
            System.out.println(testIntegersPQ.poll());
        }</code></pre><p>O resultado do programa acima é este:</p><pre><code class="language-bash">12
11
6
5
-1</code></pre><p>Podemos ver que o <em>comparator </em>fez bem o seu trabalho. Agora, a fila de prioridades nos dá os números inteiros em ordem descendente.</p><h3 id="fila-de-prioridades-com-objetos-do-java"><strong>Fila de prioridades com objetos do Java</strong></h3><p>Até este ponto, vimos como podemos usar strings e números inteiros com as filas de prioridades.</p><p>Na vida real, as aplicações geralmente usariam filas de prioridades com objetos personalizados do Java.</p><p>Para começar, vamos criar uma classe chamada CustomerOrder (em português, pedido do cliente), que será usada para armazenar os detalhes dos pedidos dos clientes:</p><pre><code class="language-java">public class CustomerOrder implements Comparable&lt;CustomerOrder&gt; {
    private int orderId;
    private double orderAmount;
    private String customerName;

    public CustomerOrder(int orderId, double orderAmount, String customerName) {
        this.orderId = orderId;
        this.orderAmount = orderAmount;
        this.customerName = customerName;
    }

    @Override
    public int compareTo(CustomerOrder o) {
        return o.orderId &gt; this.orderId ? 1 : -1;
    }

    @Override
    public String toString() {
        return "orderId:" + this.orderId + ", orderAmount:" + this.orderAmount + ", customerName:" + customerName;
    }

    public double getOrderAmount() {
        return orderAmount;
    }
}</code></pre><p>Esse é um caso simples de classes em Java para armazenar pedidos de clientes. Essa classe implementa a <strong>interface C<strong>omparable</strong></strong>, de modo que possamos decidir como esse objeto precisa ser ordenado na fila de prioridades.</p><p>O ordenamento é decidido pela função <strong><strong>compareTo </strong></strong>no código acima. A linha <strong><strong>o.orderId &gt; this.orderId ? 1 : -1</strong></strong> orienta a fila a ordenar em ordem descendente com base no campo <strong><strong>orderId</strong></strong>.</p><p>Abaixo vemos o código que cria uma fila de prioridades para o objeto <em>CustomerOrder</em>:</p><pre><code class="language-java">CustomerOrder c1 = new CustomerOrder(1, 100.0, "customer1");
CustomerOrder c2 = new CustomerOrder(3, 50.0, "customer3");
CustomerOrder c3 = new CustomerOrder(2, 300.0, "customer2");

Queue&lt;CustomerOrder&gt; customerOrders = new PriorityQueue&lt;&gt;();
customerOrders.add(c1);
customerOrders.add(c2);
customerOrders.add(c3);
while (!customerOrders.isEmpty()) {
	System.out.println(customerOrders.poll());
}</code></pre><p>No código acima, três pedidos de clientes foram criados e adicionados à fila de prioridades.</p><p>Ao executarmos o código, teremos o seguinte resultado:</p><pre><code class="language-bash">orderId:3, orderAmount:50.0, customerName:customer3
orderId:2, orderAmount:300.0, customerName:customer2
orderId:1, orderAmount:100.0, customerName:customer1</code></pre><p>Como esperávamos, o resultado vem em ordem descendente com base no campo <strong><strong>orderId</strong></strong>.</p><h3 id="como-far-amos-para-priorizar-com-base-no-campo-orderamount"><strong>Como faríamos para priorizar com base no campo orderAmount?</strong></h3><p>Mais uma vez, temos um cenário da vida real. Digamos que, por padrão, o objeto <em>CustomerOrder</em> é priorizado pelo campo <em>orderId</em>. No entanto, precisamos de um modo de priorizá-lo com base no campo <em>orderAmount</em> (em português, valor do pedido).</p><p>Você pode pensar de imediato que deveremos modificar a função <strong><strong>compareTo </strong></strong>na classe <strong><strong>CustomerOrder</strong></strong> para ordenar com base no campo <em>orderAmount</em>.</p><p>A classe <strong><strong>CustomerOrder</strong></strong>, no entanto, pode ser usada em diversos lugares da aplicação. Modificar a função <strong>compareTo </strong>diretamente interferiria com o resto da aplicação, portanto.</p><p>A solução para isso é bastante simples: podemos criar um <em>comparator</em> personalizado para a classe <strong>CustomerOrder</strong> e usá-lo em conjunto com a fila de prioridades.</p><p>Abaixo, vemos o código para o <em>comparator </em>personalizado:</p><pre><code class="language-java"> static class CustomerOrderComparator implements Comparator&lt;CustomerOrder&gt; {

        @Override
        public int compare(CustomerOrder o1, CustomerOrder o2)
        {
            return o1.getOrderAmount() &lt; o2.getOrderAmount() ? 1 : -1;
        }
    }</code></pre><p>Ele é bastante semelhante ao <em>comparator</em> personalizado de números inteiros que vimos anteriormente.</p><p>A linha <code>o1.getOrderAmount() &lt; o2.getOrderAmount() ? 1 : -1;</code> indica que precisamos priorizar com base na ordem descendente de <strong><strong>orderAmount</strong></strong>.</p><p>Aqui vemos o código que cria a fila de prioridades:</p><pre><code class="language-java">  CustomerOrder c1 = new CustomerOrder(1, 100.0, "customer1");
        CustomerOrder c2 = new CustomerOrder(3, 50.0, "customer3");
        CustomerOrder c3 = new CustomerOrder(2, 300.0, "customer2");
        Queue&lt;CustomerOrder&gt; customerOrders = new PriorityQueue&lt;&gt;(new CustomerOrderComparator());
        customerOrders.add(c1);
        customerOrders.add(c2);
        customerOrders.add(c3);
        while (!customerOrders.isEmpty()) {
            System.out.println(customerOrders.poll());
        }</code></pre><p>No código acima, passamos o <em>comparator </em>para a fila de prioridades na linha de código que diz:</p><pre><code class="language-java">Queue&lt;CustomerOrder&gt; customerOrders = new PriorityQueue&lt;&gt;(new CustomerOrderComparator());</code></pre><p>Abaixo, vemos o resultado ao executar esse código:</p><pre><code class="language-bash">orderId:2, orderAmount:300.0, customerName:customer2
orderId:1, orderAmount:100.0, customerName:customer1
orderId:3, orderAmount:50.0, customerName:customer3</code></pre><p>Podemos ver que os dados vêm em ordem descendente com base no campo <em>orderAmount</em>.</p><h2 id="c-digo"><strong>Código</strong></h2><p>Todo o código que discutimos neste artigo pode ser encontrado neste <a href="https://github.com/aditya-sridhar/java-priority-queue-example">repositório do GitHub</a>.</p><h2 id="parab-ns-"><strong>Parabéns!</strong></h2><p>Você, agora, sabe como usar filas de prioridades em Java.</p><h2 id="sobre-o-autor"><strong>Sobre o autor</strong></h2><p>O autor é um apaixonado por tecnologia e segue os avanços no campo. Ele também gosta de auxiliar as outras pessoas com seu conhecimento em tecnologia.</p><p>Você pode entrar em contato com ele por sua <a href="https://www.linkedin.com/in/aditya1811/">conta no LinkedIn</a>.</p><p>Você também pode seguir o autor no <a href="https://twitter.com/adityasridhar18" rel="noopener">Twitter</a>.</p><p>Por fim, você pode ler mais artigos escritos por ele (em inglês) no <a href="https://adityasridhar.com/">blog do autor</a>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Métodos de array em Java – como imprimir um array em Java ]]>
                </title>
                <description>
                    <![CDATA[ Um array é uma estrutura de dados utilizada para armazenar dados de um mesmo tipo. Arrays armazenam seus elementos na memória de modo contíguo. Em Java, arrays são objetos. Todos os métodos da classe dos objetos podem ser invocados em um array. Podemos armazenar um número fixo de elementos em ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/metodos-de-array-em-java-como-imprimir-um-array-em-java/</link>
                <guid isPermaLink="false">631a10a9281b1606c8fcd5c1</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Marcelo Gimenes de Oliveira ]]>
                </dc:creator>
                <pubDate>Tue, 27 Dec 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/11/Untitled-design--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</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>Um array é uma estrutura de dados utilizada para armazenar dados de um mesmo tipo. Arrays armazenam seus elementos na memória de modo contíguo.</p><p>Em Java, arrays são objetos. Todos os métodos da classe dos objetos podem ser invocados em um array. Podemos armazenar um número fixo de elementos em um array.</p><p>Vamos declarar um array de um tipo primitivo simples:</p><pre><code class="language-java">int[] intArray = {2,5,46,12,34};</code></pre><p>Agora, vamos tentar imprimi-lo com o método <code>System.out.println()</code>:</p><pre><code class="language-java">System.out.println(intArray);
// Resultado: [I@74a14482</code></pre><p>Por que o Java não imprimiu nosso array? O que está acontecendo por baixo dos panos?</p><p>O método <code>System.out.println()</code> converte o objeto que passamos para uma string chamando o método <code>String.valueOf()</code>. Se olharmos para a implementação do método <code>String.valueOf()</code>, veremos isso:</p><pre><code class="language-java">public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}</code></pre><p>Se o objeto passado é <code>null</code> ele retorna <em>null</em>. Senão, ele chama <code>obj.toString()</code>. No final, <code>System.out.println()</code> chama <code>toString()</code> para imprimir a saída.</p><p>Se a classe daquele objeto não sobrescreve a implementação de <code>Object.toString()</code>, ele chamará o método <code>Object.toString()</code>.</p><p><code>Object.toString()</code> retorna <code>getClass().getName()+</code><strong><strong><strong><strong><code>‘@’</code></strong></strong></strong></strong><code>+Integer.toHexString(hashCode())</code>. Em outras palavras, ele simplesmente retornará: "nome_da_classe@código_hash_do_objeto".</p><p>No nosso resultado anterior <code>[I@74a14482</code> , o <code>[</code> constata que isso é um array, e <code>I</code> significa int (número inteiro, o tipo do array). <code>74a14482</code> é a representação em hexadecimal sem sinal do código hash do array.</p><p>Sempre que criarmos nossas próprias classes, é uma boa prática sobrescrever o método <code>Object.toString()</code>.</p><p>Não podemos imprimir arrays em Java simplesmente usando o método <code>System.out.println()</code>. Em vez disso, essas são algumas maneiras de imprimir um array:</p><ol><li>Laços: laço <em>for</em> e laço <em>for-each</em></li><li>Método <code>Arrays.toString()</code></li><li>Método <code>Arrays.deepToString()</code></li><li>Método <code>Arrays.asList()</code></li><li>Interface Iterator do Java</li><li>API Stream do Java</li></ol><p>Vamos vê-las uma por uma.</p><h1 id="1-la-os-la-o-for-e-la-o-for-each"><strong>1. Laços: laço <em>for</em> e laço <em>for-each</em></strong></h1><p>Aqui está um exemplo de um laço <em>for</em>:</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]);
    // Resultado: 25461234
}</code></pre><p>Todas as classes <em>wrapper </em>sobrescrevem <code>Object.toString()</code> e retornam uma representação dos seus valores em string.</p><p>Aqui está um laço for-each:</p><pre><code class="language-java">int[] intArray = {2,5,46,12,34};

for(int i: intArray){
    System.out.print(i);
    // Resultado: 25461234
}</code></pre><h1 id="2-m-todo-arrays-tostring-"><strong>2. Método Arrays.toString()</strong></h1><p><code>Arrays.toString()</code> é um método estático da classe Arrays que pertence ao pacote <code>java.util</code>. Ele retorna uma representação em string do conteúdo do array especificado. Podemos imprimir arrays unidimensionais usando esse método.</p><p>Os elementos do array são convertidos para string usando o método <code>String.valueOf()</code>, desta forma:</p><pre><code class="language-java">int[] intArray = {2,5,46,12,34};
System.out.println(Arrays.toString(intArray));
// Resultado: [2, 5, 46, 12, 34]</code></pre><p>Para um array de referências, temos que ter certeza de que a classe dessas referências sobrescreve o método <code>Object.toString()</code>.</p><p>Por exemplo:</p><pre><code class="language-java">public class Test {
    public static void main(String[] args) {
        Student[] students = {new Student("John"), new Student("Doe")};
        
        System.out.println(Arrays.toString(students));
        // Resultado: [Student{name='John'}, Student{name='Doe'}]
    }
}

class Student {
    private String name;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" + "name='" + name + '\'' + '}';
    }
}</code></pre><p>Esse método não é apropriado para arrays multidimensionais. Ele converte arrays multidimensionais em strings usando o método <code>Object.toString()</code>, o que retorna suas identidades ao invés de seus conteúdos.</p><p>Por exemplo:</p><pre><code class="language-java">// Criando um array multidimensional
int[][] multiDimensionalArr = { {2,3}, {5,9} };

System.out.println(Arrays.toString(multiDimensionalArr));
// Resultado: [[I@74a14482, [I@1540e19d]</code></pre><p>Com a ajuda do método <code>Arrays.deepToString()</code>, podemos imprimir arrays multidimensionais.</p><h1 id="3-m-todo-arrays-deeptostring-"><strong>3. Método Arrays.deepToString()</strong></h1><p><code>Arrays.deepToString()</code> retorna uma representação em string dos "conteúdos profundos" do array especificado.</p><p>Se um elemento é um array de tipo primitivo, ele é convertido para string através da invocação da sobrecarga apropriada de <code>Arrays.toString()</code>.</p><p>Aqui está um exemplo de um array multidimensional de tipo primitivo:</p><pre><code class="language-java">// criando o array multidimensional
int[][] multiDimensionalArr = { {2,3}, {5,9} };

System.out.println(Arrays.deepToString(multiDimensionalArr));
// Resultado: [[2, 3], [5, 9]]</code></pre><p>Se um elemento é um array de referências, ele é convertido para string através de uma chamada recursiva do método <code>Arrays.deepToString()</code>.</p><pre><code class="language-java">Teacher[][] teachers = 
{{ new Teacher("John"), new Teacher("David") }, {new Teacher("Mary")} };

System.out.println(Arrays.deepToString(teachers));
// Resultado: 
[[Teacher{name='John'}, Teacher{name='David'}],[Teacher{name='Mary'}]]</code></pre><p>Temos que sobrescrever o método <code>Object.toString()</code> na nossa classe Teacher.</p><p>Se você está curioso sobre como ele faz a recursão, aqui está o <a href="http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/be44bff34df4/src/share/classes/java/util/Arrays.java#l4611">código-fonte</a> para o método <code>Arrays.deepToString()</code>.</p><p><strong>Observação<strong><strong><strong>:</strong></strong></strong></strong> arrays de referência unidimensionais também podem ser impressos usando esse método. Por exemplo:</p><pre><code class="language-java">Integer[] oneDimensionalArr = {1,4,7};

System.out.println(Arrays.deepToString(oneDimensionalArr));
// Resultado: [1, 4, 7]</code></pre><h1 id="4-m-todo-arrays-aslist-"><strong>4. Método Arrays.asList()</strong></h1><p>Esse método retorna uma lista de tamanho fixo criada a partir do array especificado.</p><pre><code class="language-java">Integer[] intArray = {2,5,46,12,34};

System.out.println(Arrays.asList(intArray));
// Resultado: [2, 5, 46, 12, 34]</code></pre><p>Mudamos o tipo de int para Integer, porque List é uma coleção que armazena uma lista de objetos. Quando estamos convertendo um array em uma lista, o array deve ser de referências.</p><p>Java chama <code>Arrays.asList(intArray).toString()</code>. Internamente, essa técnica usa o método <code>toString()</code> do tipo dos elementos que estão na lista.</p><p>Temos outro exemplo abaixo, com a nossa classe customizada Teacher:</p><pre><code class="language-java">Teacher[] teacher = { new Teacher("John"), new Teacher("Mary") };

System.out.println(Arrays.asList(teacher));
// Resultado: [Teacher{name='John'}, Teacher{name='Mary'}]</code></pre><p><strong>OBSERVAÇÃO<strong>:</strong></strong> não podemos imprimir arrays multidimensionais usando esse método. Por exemplo:</p><pre><code class="language-java">Teacher[][] teachers = 
{{ new Teacher("John"), new Teacher("David") }, { new Teacher("Mary") }};
        
System.out.println(Arrays.asList(teachers));

// Resultado: [[Lcom.thano.article.printarray.Teacher;@1540e19d, [Lcom.thano.article.printarray.Teacher;@677327b6]</code></pre><h1 id="5-interface-iterator"><strong>5. Interface Iterator</strong></h1><p>Do mesmo modo que com o laço <em>for-each</em>, podemos usar a interface Iterator para percorrer os elementos do array e imprimi-los.</p><p>Um objeto Iterator pode ser criado invocando o método <code>iterator()</code> em uma <em>Collection</em>. Esse objeto será usado para iterar sobre os elementos dessa <em>Collection</em>.</p><p>Aqui está um exemplo de como poderíamos imprimir um array usando a interface Iterator:</p><pre><code class="language-java">Integer[] intArray = {2,5,46,12,34};

// Criando uma List de Integer
List&lt;Integer&gt; list = Arrays.asList(intArray);

// Criando um Iterator dessa lista de números inteiros
Iterator&lt;Integer&gt; it = list.iterator();

// Se a lista tiver elementos para serem iterados
while(it.hasNext()) {
    System.out.print(it.next());
    // Resultado: 25461234
}</code></pre><h1 id="6-api-stream-do-java"><strong>6. API Stream do Java</strong></h1><p>A API Stream é usada para processar coleções de objetos. Uma stream é uma sequência de objetos. Streams não mudam a estrutura de dados original. Elas apenas fornecem o resultado de cada operação requisitada.</p><p>Com a ajuda da operação de terminal <code>forEach()</code>, podemos iterar sobre cada elemento da stream.</p><p>Por exemplo:</p><pre><code class="language-java">Integer[] intArray = {2,5,46,12,34};

Arrays.stream(intArray).forEach(System.out::print);
// Resultado: 25461234</code></pre><p>Agora, sabemos como imprimir um array em Java.</p><p>Obrigado pela leitura.</p><p>Imagem de <a href="https://unsplash.com/@acharki95?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Aziz Acharki</a>, extraída do <a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>.</p><p>Você pode ler outros artigos do autor (em inglês) no <a href="https://medium.com/@mvthanoshan9/object-oriented-programming-principles-in-java-820919dced1a">Medium</a> e no <a href="https://www.freecodecamp.org/news/author/thanoshan/">freeCodeCamp</a>.</p><p><strong>Boa programação para você<strong><strong><strong>!</strong></strong></strong></strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ As principais estruturas de dados que você deve conhecer para sua próxima entrevista de programação ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Fahim ul Haq Niklaus Wirth, um cientista da computação suíço, escreveu um livro em 1976 intitulado Algorithms + Data Structures = Programs (em português, "Algoritmos + Estrutura de Dados = Programas"). Mais de 40 anos depois, essa equação permanece sendo verdade. É por isso que aspirantes a posições ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/as-principais-estruturas-de-dados-que-voce-deve-conhecer-para-sua-proxima-entrevista-de-programacao/</link>
                <guid isPermaLink="false">6290fd2689eb8b0539f446b2</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Rafael B. Pires ]]>
                </dc:creator>
                <pubDate>Thu, 16 Jun 2022 01:46:16 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/06/1_s6hhrgR5_tXpO_j7uKaHMw-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/the-top-data-structures-you-should-know-for-your-next-coding-interview-36af0831f5e3/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The top data structures you should know for your next coding interview</a>
      </p><p>Escrito por: Fahim ul Haq</p><p>Niklaus Wirth, um cientista da computação suíço, escreveu um livro em 1976 intitulado <em><em>Algorithms + Data Structures = Programs</em></em> (em português, "Algoritmos + Estrutura de Dados = Programas").</p><p>Mais de 40 anos depois, essa equação permanece sendo verdade. É por isso que aspirantes a posições em engenharia de software precisam demonstrar sua compreensão de estruturas de dados ao se candidatarem a um emprego na área.</p><p>Quase todos os problemas exigem que o candidato demonstre uma compreensão profunda das estruturas de dados. Não importa se você acabou de se formar (em uma universidade ou em um bootcamp de programação) ou se você tem décadas de experiência.</p><p>Às vezes, as perguntas em uma entrevista mencionam explicitamente uma estrutura de dados, por exemplo, "dada uma árvore binária". Outras vezes, elas estão implícitas, como em "queremos rastrear o número de livros associados a cada autor".</p><p>Aprender estruturas de dados é essencial, mesmo que você esteja apenas tentando melhorar seu trabalho atual. Vamos começar entendendo o básico.</p><h3 id="o-que-uma-estrutura-de-dados"><strong>O que é uma estrutura de dados?</strong></h3><p>Em termos simples, uma estrutura de dados é um contêiner que armazena dados em um layout específico. Esse "layout" permite que a estrutura de dados seja eficiente em algumas operações e ineficiente em outras. Seu objetivo é entender as estruturas de dados de modo que você consiga escolher a mais adequada para o problema apresentado.</p><h4 id="por-que-precisamos-de-estruturas-de-dados"><strong>Por que precisamos de estruturas de dados<strong><strong>?</strong></strong></strong></h4><p>Como as estruturas de dados são usadas para armazenar dados de uma forma organizada, e como os dados são a entidade mais crucial nas ciências da computação, fica claro o verdadeiro valor das estruturas de dados.</p><p>Independentemente do problema que você esteja resolvendo, de uma forma ou de outra, terá que lidar com dados — seja o salário de um empregado, preços de ações, uma lista de compras, ou mesmo uma simples lista telefônica.</p><p>Com base em diferentes cenários, os dados precisam ser guardados em um formato específico. Temos um punhado de estrutura de dados que satisfazem nossa necessidade de armazenar dados em diferentes formatos.</p><h3 id="estruturas-de-dados-mais-utilizadas"><strong>Estruturas de dados mais utilizadas </strong></h3><p>Primeiro, listemos as estruturas de dados mais utilizadas e, então, vamos explorá-las uma a uma:</p><ol><li>Arrays</li><li>Pilhas</li><li>Filas</li><li>Listas vinculadas</li><li>Árvores </li><li>Grafos</li><li>Tries (elas são árvores, efetivamente, mas ainda assim é bom tratar delas separadamente)</li><li>Hash tables</li></ol><h3 id="arrays"><strong>Arrays</strong></h3><p>Um array é a estrutura de dados mais simples e mais amplamente utilizada. Outras estruturas de dados como pilhas e filhas são derivadas dos arrays.</p><p>Aqui temos uma imagem de um array simples de tamanho 4, contendo elementos (1, 2, 3 e 4).</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/06/B4CncYOv-dN76B45UXdVrfat45MvgQ9b8atv.png" class="kg-image" alt="B4CncYOv-dN76B45UXdVrfat45MvgQ9b8atv" width="396" height="158" loading="lazy"></figure><p>Cada elemento de dados recebe um valor numérico positivo chamado de <strong>índice</strong>, o qual corresponde à posição daquele item dentro do array. A maioria das linguagens de programação define o índice inicial do array como 0.</p><p>A seguir, temos os dois tipos de arrays:</p><ul><li>Arrays unidimensionais (como o mostrado acima)</li><li>Arrays multidimensionais (arrays dentro de arrays)</li></ul><h4 id="opera-es-b-sicas-com-arrays"><strong>Operações básicas com arrays</strong></h4><ul><li>Insert (inserir) — Insere um elemento em um determinado índice</li><li>Get (receber) — Retorna um elemento em um determinado índice</li><li>Delete (excluir) — Remove um elemento em um determinado índice</li><li>Size (tamanho) — Obtém o número total de elementos de um array</li></ul><h4 id="perguntas-mais-comuns-sobre-arrays-em-entrevistas"><strong>Perguntas mais comuns sobre arrays em entrevistas</strong></h4><ul><li>Encontre o segundo menor elemento de um array</li><li>Primeiros inteiros não repetidos de um array</li><li>Mescle dois arrays ordenados</li><li>Reordene os valores positivos e negativos em um array</li></ul><h3 id="pilhas-stacks-"><strong>Pilhas (Stacks)</strong></h3><p>Todos temos familiaridade com a famosa opção de <strong>desfazer</strong>, que está presente em quase todos os aplicativos. Você já se perguntou como ela funciona? A ideia: você armazena na memória os estados anteriores de seu trabalho (os quais são limitados a um número específico) em uma ordem tal que o último estado apareça primeiro. Isso não pode ser feito usando-se apenas arrays. É aí que as <strong><em>pilhas</em></strong> passam a ser muito úteis. </p><p>Um exemplo de uma pilha na vida real seria um conjunto de livros colocados uns sobre os outros em uma ordem vertical. Para visualizar o livro que está em algum lugar do meio, você precisará remover todos os livros colocados em cima dele. É assim que funciona o método LIFO (acrônimo para a expressão inglesa "Last In, First Out" — em português, "o último a entrar é o primeiro a sair").</p><p>Aqui temos uma imagem de uma pilha contendo três elementos de dados (1, 2 e 3), em que 3 está no topo e será removido primeiro:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/06/BP-lD2OxkMbIQI2iZD-jxgIPlANlsMTqwnLP.png" class="kg-image" alt="BP-lD2OxkMbIQI2iZD-jxgIPlANlsMTqwnLP" width="462" height="318" loading="lazy"><figcaption>(Na imagem: <em>top </em>= topo.)</figcaption></figure><h4 id="opera-es-b-sicas-com-pilhas"><strong>Operações básicas com pilhas</strong></h4><ul><li>Push (empilhar) — Insere um elemento no topo</li><li>Pop (desempilhar) — Retorna o elemento do topo após removê-lo da pilha</li><li>isEmpty (éVazio) — Retorna verdadeiro se a pilha estiver vazia</li><li>Top (topo) — Retorna o elemento do topo sem removê-lo da pilha</li></ul><h4 id="perguntas-mais-comuns-sobre-pilhas-em-entrevistas"><strong>Perguntas mais comuns sobre pilhas em entrevistas</strong></h4><ul><li>Calcule o valor de uma expressão pós-fixada usando uma pilha</li><li>Ordene valores em uma pilha</li><li>Verifique se os parênteses estão balanceados em uma expressão</li></ul><h3 id="filas-queues-"><strong>Filas (Queues)</strong></h3><p>Similares às pilhas, as <strong><em>filas</em></strong> são uma outra estrutura de dados linear que armazena elementos de forma sequencial. A única diferença significativa entre pilhas e filas é que, em vez de usar o método LIFO, as filas usam a lógica FIFO, um acrônimo para "First in, First Out" (em português, "o primeiro a entrar é o primeiro a sair").</p><p>Um exemplo perfeito de uma fila na vida real: uma fileira de pessoas aguardando em uma bilheteria. Se uma nova pessoa chega, ela se junta às demais ao final da fila, não no começo — e a pessoa em pé à frente da fileira será a primeira a receber o ingresso e, portanto, deixar a fila.</p><p>Aqui temos uma imagem de uma fila contendo quatro elementos de dados (1, 2, 3 e 4), em que 1 está no topo e será removido primeiro:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/06/C2riLJTPBVpSI-3o5Cx9IrQ16LZi1kLrqYXo.png" class="kg-image" alt="C2riLJTPBVpSI-3o5Cx9IrQ16LZi1kLrqYXo" width="542" height="734" loading="lazy"><figcaption>(Na imagem:<em> remove previous elements</em> = remove elementos anteriores; <em>front </em>= frente; <em>back </em>= fundo; <em>insert new elements</em> = insere novos elementos.)</figcaption></figure><h4 id="opera-es-b-sicas-com-filas"><strong>Operações básicas com filas</strong></h4><ul><li>Enqueue (enfileirar) — Insere um elemento ao final da fila</li><li>Dequeue (desenfileirar) — Remove um elemento do início da fila</li><li>isEmpty (éVazio) — Retorna verdadeiro se a fila estiver vazia</li><li>Top (topo) — Retorna o primeiro elemento da fila</li></ul><h4 id="perguntas-mais-comuns-sobre-filas-em-entrevistas"><strong>Perguntas mais comuns sobre filas em entrevistas</strong></h4><ul><li>Implemente uma pilha usando uma fila</li><li>Ordene inversamente os primeiros k elementos de uma fila</li><li>Gere números binários de 1 a n usando uma fila</li></ul><h3 id="lista-vinculada-linked-list-"><strong>Lista vinculada (<strong><strong>Linked </strong></strong>l<strong><strong>ist</strong></strong>)</strong></h3><p>Uma lista vinculada (ou encadeada) é outra estrutura de dados linear importante que pode parecer com arrays à primeira vista, mas que difere em relação à alocação de memória, à estrutura interna e a como as operações básicas de inserção e exclusão são realizadas.</p><p>Uma lista vinculada é como uma cadeia de nós, onde cada nó contém informações como dados e um ponteiro para o nó seguinte na cadeia. Há um ponteiro de cabeça (head), que aponta para o primeiro elemento da lista vinculada e, se a lista estiver vazia, ele simplesmente aponta para nulo ou nada.</p><p>As listas vinculadas são utilizadas para implementar sistemas de arquivos, tabelas hash e listas de adjacência.</p><p>Aqui está uma representação visual da estrutura interna de uma lista vinculada:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/06/ezrkbpSyblh3famnGsgIHiRvHV9CKODu0tPw.png" class="kg-image" alt="ezrkbpSyblh3famnGsgIHiRvHV9CKODu0tPw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/06/ezrkbpSyblh3famnGsgIHiRvHV9CKODu0tPw.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/06/ezrkbpSyblh3famnGsgIHiRvHV9CKODu0tPw.png 800w" sizes="(min-width: 720px) 720px" width="800" height="147" loading="lazy"><figcaption>(Na imagem: <em>head </em>= cabeça; <em>data </em>= dados; <em>pointer </em>= ponteiro; <em>null </em>= nulo.)</figcaption></figure><p>A seguir, temos os tipos de listas vinculadas:</p><ul><li>Lista simplesmente vinculada (unidirecional)</li><li>Lista duplamente vinculada (bidirecional)</li></ul><h4 id="opera-es-b-sicas-com-listas-vinculadas"><strong>Operações básicas com listas vinculadas</strong></h4><ul><li><em><em>InsertAtEnd </em></em>(inserirAoFim) — Insere determinado elemento ao fim da lista vinculada</li><li><em><em>InsertAtHead</em></em> <em><em> </em></em>(inserirAoInício) — Insere determinado elemento no início/cabeça da lista vinculada</li><li><em><em>Delete </em></em>(excluir) — Exclui determinado elemento da lista vinculada</li><li><em><em>DeleteAtHead </em></em>(excluirAoInício) — Exclui o primeiro elemento da lista vinculada</li><li><em><em>Search</em></em> (busca) — Retorna determinado elemento da lista vinculada</li><li><em><em>isEmpty </em></em>(éVazio)— Retorna verdadeiro se a lista vinculada estiver vazia</li></ul><h4 id="perguntas-mais-comuns-sobre-listas-vinculadas-em-uma-entrevista"><strong>Perguntas mais comuns sobre listas vinculadas em uma entrevista</strong></h4><ul><li>Ordene inversamente uma lista vinculada</li><li>Detecte um loop (laço) em uma lista vinculada</li><li>Retorne o enésimo nó partindo do final de uma lista vinculada</li><li>Remova elementos duplicados de uma lista vinculada</li></ul><h3 id="grafos-graphs-"><strong>Grafos (<strong><strong>Graphs</strong></strong>)</strong></h3><p>Um <strong><em>grafo</em></strong> é um conjunto de nós que estão conectados uns aos outros na forma de uma rede. Os nós também são chamados de vértices. Um <strong>par(x,y)</strong> é chamado de <strong>aresta</strong>, indicando que o vértice <strong>x </strong>está conectado ao vértice <strong>y</strong>. Uma aresta pode conter peso/custo, mostrando qual o custo exigido para se atravessar do vértice x para y.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/06/0MsvzasAr6vS6bnvozjRAa5iBnEDKn9Cty0D.png" class="kg-image" alt="0MsvzasAr6vS6bnvozjRAa5iBnEDKn9Cty0D" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/06/0MsvzasAr6vS6bnvozjRAa5iBnEDKn9Cty0D.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/06/0MsvzasAr6vS6bnvozjRAa5iBnEDKn9Cty0D.png 800w" sizes="(min-width: 720px) 720px" width="800" height="425" loading="lazy"><figcaption>(Na imagem: <em>vertex </em>= vértice; <em>edge </em>= aresta.)</figcaption></figure><p>Tipos de grafos:</p><ul><li>Grafo não direcionado</li><li>Grafo direcionado (ou orientado)</li></ul><p>Em uma linguagem de programação, os grafos podem ser representados usando-se duas formas:</p><ul><li>Matriz de adjacência</li><li>Lista de adjacência</li></ul><p>Algoritmos comuns para varredura de grafos:</p><ul><li>Busca em largura (em inglês, <em>Breadth First Search</em>)</li><li>Busca em profundidade (em inglês, <em>Depth First Search</em>)</li></ul><h4 id="perguntas-mais-comuns-sobre-grafos-em-uma-entrevista"><strong>Perguntas mais comuns sobre grafos em uma entrevista</strong></h4><ul><li>Implemente algoritmos de busca em largura e em profundidade</li><li>Verifique se um grafo é ou não uma árvore</li><li>Conte o número de arestas em um grafo</li><li>Encontre o caminho mínimo entre dois vértices</li></ul><h3 id="-rvores-trees-"><strong>Árvores (<strong><strong>Trees</strong></strong>)</strong></h3><p>Uma <strong><em>árvore</em></strong> é uma estrutura de dados hierárquica que consiste em vértices (nós) e arestas que os conectam. Árvores são semelhantes a grafos, mas o ponto-chave que diferencia uma árvore de um grafo é que, em uma árvore, não deve haver ciclos.</p><p>Árvores são amplamente utilizadas em Inteligência Artificial e em algoritmos complexos para fornecer um mecanismo de armazenamento eficiente para a resolução de problemas.</p><p>A seguir, temos a imagem de uma árvore simples, além da nomenclatura básica usada para essa estrutura de dados:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/06/VPUnmQO8rMoLGMqMe24EnoJ3uS72JZdMt48w.png" class="kg-image" alt="VPUnmQO8rMoLGMqMe24EnoJ3uS72JZdMt48w" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/06/VPUnmQO8rMoLGMqMe24EnoJ3uS72JZdMt48w.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/06/VPUnmQO8rMoLGMqMe24EnoJ3uS72JZdMt48w.png 800w" sizes="(min-width: 720px) 720px" width="800" height="352" loading="lazy"><figcaption>(Na imagem: <em>root </em>= raiz; <em>parent </em>= pai; <em>child </em>= filho; <em>leaf </em>= folha; <em>sibling </em>= irmão.)</figcaption></figure><p>A seguir temos os tipos de árvores:</p><ul><li>Árvore n-ária</li><li>Árvore balanceada</li><li>Árvore binária</li><li>Árvore binária de busca</li><li>Árvore AVL</li><li>Árvore rubro-negra </li><li>Árvore 2-3</li></ul><p>Destes tipos, a árvore binária e a árvore binária de busca são as mais comumente utilizadas.</p><h4 id="perguntas-mais-comuns-sobre-rvores-em-uma-entrevista"><strong>Perguntas mais comuns sobre árvores em uma entrevista</strong></h4><ul><li>Encontre a altura de uma árvore binária</li><li>Encontre o k-ésimo valor máximo em uma árvore binária de busca</li><li>Encontre nós a uma distância "k" da raiz</li><li>Encontre ancestrais de um determinado nó em uma árvore binária</li></ul><h3 id="trie"><strong>Trie</strong></h3><p>A <strong><em>Trie</em></strong>, também conhecida como "árvore de prefixos", é uma estrutura de dados em formato de árvore que se mostra bastante eficiente para solução de problemas relacionados a <em>strings</em>. Ela fornece recuperação rápida e é usada principalmente para pesquisar palavras em um dicionário, fornecer sugestões automáticas em um mecanismo de busca, e até mesmo para roteamento de IP.</p><p>Aqui temos uma ilustração de como três palavras "top", "thus" e "their" são armazenadas em uma Trie:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/06/lSNi21Wr4P6eMKDwLMQ5rijHhA-lBlovlc40-1.png" class="kg-image" alt="lSNi21Wr4P6eMKDwLMQ5rijHhA-lBlovlc40-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/06/lSNi21Wr4P6eMKDwLMQ5rijHhA-lBlovlc40-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/06/lSNi21Wr4P6eMKDwLMQ5rijHhA-lBlovlc40-1.png 800w" sizes="(min-width: 720px) 720px" width="800" height="1093" loading="lazy"><figcaption>(Na imagem: <em>root </em>= raiz.)</figcaption></figure><p>As palavras são armazenadas de cima para baixo, onde os nós de cor verde "p", "s" e "r" indicam os finais de "top", "thus" e "their", respectivamente.</p><p>Perguntas mais comuns sobre Tries em uma entrevista:</p><ul><li>Conte o número total de palavras em uma Trie</li><li>Imprima todas as palavras armazenadas em uma Trie</li><li>Classifique os elementos de um array usando uma Trie</li><li>Forme palavras de um dicionário usando Trie</li><li>Construa um dicionário <a href="https://pt.wikipedia.org/wiki/T9_(texto_previs%C3%ADvel)">T9</a></li></ul><h3 id="hash-table"><strong><strong><strong>Hash </strong></strong>t<strong><strong>able</strong></strong></strong></h3><p><strong>Hashing</strong> é um processo usado para identificar objetos de forma única e armazenar cada um deles em algum índice único pré-calculado chamado de "chave". Assim, o objeto é armazenado na forma de um par "chave-valor", e a coleção desses itens é chamada de "dicionário". Cada objeto pode ser pesquisado usando sua respectiva chave. Existem diferentes estruturas de dados baseadas em hashing, mas a estrutura de dados mais comumente usada é a <strong><strong>hash table</strong></strong> (também conhecida por "tabela de dispersão").</p><p>Hash tables são normalmente implementadas usando-se arrays.</p><p>O desempenho do hashing como estrutura de dados depende de três fatores:</p><ul><li>A função de hashing </li><li>O tamanho da hash table</li><li>O método de resolução de colisões</li></ul><p>Aqui temos uma ilustração de como o hash é mapeado em um array. O índice deste array é calculado por meio de uma função de hashing.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/06/zV3x2Pxt0JFt7UjokTKNx24HFmM3t-6phDV2.png" class="kg-image" alt="zV3x2Pxt0JFt7UjokTKNx24HFmM3t-6phDV2" width="348" height="394" loading="lazy"><figcaption>(Na imagem: <em>key </em>= chave; <em>data </em>= valor.)</figcaption></figure><h4 id="perguntas-mais-comuns-sobre-hashing-em-uma-entrevista"><strong>Perguntas mais comuns sobre hashing em uma entrevista</strong></h4><ul><li>Encontre pares simétricos em um array</li><li>Trace o caminho completo de uma jornada</li><li>Descubra se um array é um subconjunto de outro array</li><li>Verifique se determinados arrays são disjuntos (não possuem elementos em comum)</li></ul><p>Acima estão as oito principais estruturas de dados que você deve, definitivamente, conhecer antes de começar uma entrevista de programação. </p><p><em>Se você está procurando por mais material sobre estruturas de dados para entrevistas de programação, dê uma olhada nesses cursos interativos e baseados em desafios: Data Structures for Coding Interviews (<a href="https://www.educative.io/collection/5642554087309312/5634727314718720" rel="noopener">Python</a>, <a href="https://www.educative.io/collection/5642554087309312/5724822843686912" rel="noopener">Java</a> ou <a href="https://www.educative.io/collection/5642554087309312/5663204961157120" rel="noopener">JavaScript</a> - em inglês).</em></p><p><em>Para perguntas mais avançadas, confira<em> <a href="https://www.educative.io/collection/5642554087309312/5679846214598656" rel="noopener">Coderust 3.0: Faster Coding Interview Preparation with Interactive Challenges &amp; Visualizations</a></em> (em inglês)<em>.</em></em></p><p>Se você está se preparando para entrevistas em engenharia de software, aqui você encontra um <a href="https://medium.com/educative/3-month-coding-interview-bootcamp-904422926ce8">roteiro abrangente para se preparar para entrevistas de programação</a> (em inglês).</p><p>Boa sorte e bom aprendizado! :)</p><p><em><strong>Nota do tradutor:</strong> O freeCodeCamp.org possui um vasto material gratuito e em português para auxiliá-lo na <a href="https://www.freecodecamp.org/portuguese/learn/coding-interview-prep">preparação para entrevistas de programação</a>, incluindo inúmeros exercícios com algoritmos e estruturas de dados.</em></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Métodos de arrays em Java – como imprimir um array em Java ]]>
                </title>
                <description>
                    <![CDATA[ Um array é uma estrutura de dados usada para armazenar dados do mesmo tipo. Os arrays armazenam seus elementos em localizações sequenciais contínuas da memória. Em Java, arrays são objetos. Todos os métodos da classe Object podem ser invocados em um array. Podemos armazenar um número fixo de elementos em ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/metodos-de-arrays-em-java-como-imprimir-um-array-em-java/</link>
                <guid isPermaLink="false">6295f8e308b5de06cf9f4f6c</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Tue, 31 May 2022 11:53:38 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/05/Untitled-design--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</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>Um array é uma estrutura de dados usada para armazenar dados do mesmo tipo. Os arrays armazenam seus elementos em localizações sequenciais contínuas da memória.</p><p>Em Java, arrays são objetos. Todos os métodos da classe Object podem ser invocados em um array. Podemos armazenar um número fixo de elementos em um array.</p><p>Vamos declarar um array simples de tipo primitivo:</p><pre><code class="language-java">int[] intArray = {2,5,46,12,34};</code></pre><p>Agora, vamos tentar imprimi-lo com o método <code>System.out.println()</code>:</p><pre><code class="language-java">System.out.println(intArray);
// Resultado: [I@74a14482</code></pre><p>Por que o Java não imprimiu o array? O que está acontecendo internamente?</p><p>O método <code>System.out.println()</code> converte o objeto que passamos em uma string, chamando <code>String.valueOf()</code>. Se olharmos a implementação do método <code>String.valueOf()</code>, veremos o seguinte:</p><pre><code class="language-java">public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}</code></pre><p>Se o objeto passado para o método for <code>null</code>, ele retorna "null"; caso contrário, é chamado o método <code>obj.toString()</code>. No fim, <code>System.out.println()</code> chama <code>toString()</code> para imprimir o resultado.</p><p>Se essa classe de objeto não sobrescrever a implementação de <code>Object.toString()</code>, será chamado o método <code>Object.toString()</code>.</p><p><code>Object.toString()</code> retorna <code>getClass().getName()+<strong><strong><strong><strong>‘@’</strong></strong></strong></strong>+Integer.toHexString(hashCode())</code>. Simplificando, o que ele faz é retornar "nome da classe @ <em>hash code</em> do objeto".</p><p>Em nosso resultado anterior, <code>[I@74a14482</code>, o colchete inicial (<code>[</code>) declara que esse objeto é um array, enquanto <code>I</code> representa <em>int</em> (o tipo do array). <code>74a14482</code> é a representação hexadecimal sem sinal do <em>hash code</em> do array.</p><p>Sempre que criarmos nossas próprias classes personalizadas, é uma prática recomendada sobrescrever o método <code>Object.toString()</code>.</p><p>Não podemos imprimir arrays em Java usando um método <code>System.out.println()</code> simples. Em vez disso, aqui temos algumas maneiras de podermos imprimir arrays:</p><ol><li>Laços: laço for e laço for-each</li><li>Método <code>Arrays.toString()</code></li><li>Método <code>Arrays.deepToString()</code></li><li>Método <code>Arrays.asList()</code></li><li>Interface Iterator do Java</li><li>Stream API do Java</li></ol><p>Vejamos um por um.</p><h1 id="1-la-os-la-o-for-e-la-o-for-each"><strong>1. Laços: laço for e laço for-each </strong></h1><p>Aqui temos um exemplo de laço <em>for</em>:</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]);
    // Resultado: 25461234
}</code></pre><p>Todas as classes <em>wrapper</em> sobrescrevem o método <code>Object.toString()</code> e retornam uma representação de string de seu valor.</p><p>Aqui temos um laço <em>for-each</em>:</p><pre><code class="language-java">int[] intArray = {2,5,46,12,34};

for(int i: intArray){
    System.out.print(i);
    // Resultado: 25461234
}</code></pre><h1 id="2-m-todo-arrays-tostring-"><strong>2. Método Arrays.toString()</strong></h1><p><code>Arrays.toString()</code> é um método estático da classe array que pertence ao pacote <code>java.util</code>. Ele retorna uma representação de string do conteúdo do array especificado. Podemos imprimir arrays unidimensionais usando esse método.</p><p>Os elementos do array são convertidos em strings usando o método <code>String.valueOf()</code>, assim:</p><pre><code class="language-java">int[] intArray = {2,5,46,12,34};
System.out.println(Arrays.toString(intArray));
// Resultado: [2, 5, 46, 12, 34]</code></pre><p>Para um array com um tipo de referência, temos de nos certificar que a classe do tipo de referência sobrescreve o método <code>Object.toString()</code>.</p><p>Por exemplo:</p><pre><code class="language-java">public class Test {
    public static void main(String[] args) {
        Student[] students = {new Student("John"), new Student("Doe")};
        
        System.out.println(Arrays.toString(students));
        // Resultado: [Student{name='John'}, Student{name='Doe'}]
    }
}

class Student {
    private String name;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" + "name='" + name + '\'' + '}';
    }
}</code></pre><p>Esse método não é adequado para métodos multidimensionais. Ele converte arrays multidimensionais em strings usando <code>Object.toString()</code>, o que descreve suas identidades, em vez de seu conteúdo.</p><p>Por exemplo:</p><pre><code class="language-java">// Criação de um array multidimensional
int[][] multiDimensionalArr = { {2,3}, {5,9} };

System.out.println(Arrays.toString(multiDimensionalArr));
// Resultado: [[I@74a14482, [I@1540e19d]</code></pre><p>Com a ajuda de <code>Arrays.deepToString()</code>, podemos imprimir arrays multidimensionais.</p><h1 id="3-m-todo-arrays-deeptostring-"><strong>3. Método Arrays.deepToString() </strong></h1><p><code>Arrays.deepToString()</code> retorna uma representação de string do "conteúdo interno" do array especificado.</p><p>Se o elemento de um array for de um tipo primitivo, ele será convertido em uma string invocando a sobrecarga apropriada de <code>Arrays.toString()</code> .</p><p>Aqui temos um exemplo de array multidimensional de um tipo primitivo:</p><pre><code class="language-java">// Criação de um array multidimensional
int[][] multiDimensionalArr = { {2,3}, {5,9} };

System.out.println(Arrays.deepToString(multiDimensionalArr));
// Resultado: [[2, 3], [5, 9]]</code></pre><p>Se o elemento de um array for de tipo de referência, ele será convertido em uma string invocando <code>Arrays.deepToString()</code> recursivamente.</p><pre><code class="language-java">Teacher[][] teachers = 
{{ new Teacher("John"), new Teacher("David") }, {new Teacher("Mary")} };

System.out.println(Arrays.deepToString(teachers));
// Resultado: 
[[Teacher{name='John'}, Teacher{name='David'}],[Teacher{name='Mary'}]]</code></pre><p>Temos de sobrescrever <code>Object.toString()</code> em nossa classe Teacher.</p><p>Se estiver curioso sobre como é feita a recursão, aqui está o <a href="http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/be44bff34df4/src/share/classes/java/util/Arrays.java#l4611" rel="noopener nofollow">código-fonte</a> do método <code>Arrays.deepToString()</code>.</p><p><strong><strong>OBSERVAÇÃO<strong><strong>:</strong></strong></strong></strong> arrays unidimensionais de tipo de referência também podem ser impressos usando este método. Por exemplo:</p><pre><code class="language-java">Integer[] oneDimensionalArr = {1,4,7};

System.out.println(Arrays.deepToString(oneDimensionalArr));
// Resultado: [1, 4, 7]</code></pre><h1 id="4-m-todo-arrays-aslist-"><strong>4. Método Arrays.asList()</strong></h1><p>Este método retorna uma lista de tamanho fixo gerada pelo array especificado.</p><pre><code class="language-java">Integer[] intArray = {2,5,46,12,34};

System.out.println(Arrays.asList(intArray));
// Resultado: [2, 5, 46, 12, 34]</code></pre><p>Alteramos o tipo para Integer a partir de int, pois List é uma coleção que suporta uma lista de objetos apenas. Quando convertemos um array em uma lista, ele deve ser um array de tipo de referência.</p><p>O Java chama <code>Arrays.<em><em><em><em>asList</em></em></em></em>(intArray).toString()</code>. Essa técnica usa internamente o método <code>toString()</code> do tipo dos elementos que está dentro da lista.</p><p>Outro exemplo com nossa classe personalizada Teacher:</p><pre><code class="language-java">Teacher[] teacher = { new Teacher("John"), new Teacher("Mary") };

System.out.println(Arrays.asList(teacher));
// Resultado: [Teacher{name='John'}, Teacher{name='Mary'}]</code></pre><p><strong>OBSERVAÇÃO<strong>:</strong></strong> não podemos imprimir arrays multidimensionais usando esse método. Por exemplo:</p><pre><code class="language-java">Teacher[][] teachers = 
{{ new Teacher("John"), new Teacher("David") }, { new Teacher("Mary") }};
        
System.out.println(Arrays.asList(teachers));

// Resultado: [[Lcom.thano.article.printarray.Teacher;@1540e19d, [Lcom.thano.article.printarray.Teacher;@677327b6]</code></pre><h1 id="5-interface-iterator-do-java"><strong>5. Interface Iterator do Java</strong></h1><p>Da mesma forma que em um laço <em>for-each</em>, podemos usar a interface Iterator para percorrer elementos do array e imprimi-los.</p><p>O objeto Iterator pode ser criado invocando o método <code>iterator()</code> em uma <em>coleção</em>. Esse objeto será usado para iterar sobre os elementos daquela coleção.</p><p>Aqui temos um exemplo de como podemos imprimir um array usando a interface Iterator:</p><pre><code class="language-java">Integer[] intArray = {2,5,46,12,34};

// Criação de uma lista de Integer
List&lt;Integer&gt; list = Arrays.asList(intArray);

// Criação de um iterator da lista de Integer
Iterator&lt;Integer&gt; it = list.iterator();

// Se a lista tiver elementos que possam ser percorridos pelo Iterator
while(it.hasNext()) {
    System.out.print(it.next());
    // Resultado: 25461234
}</code></pre><h1 id="6-stream-api-do-java"><strong>6. Stream API do Java</strong></h1><p>A Stream API é usada para processar coleções de objetos. Uma stream é uma sequência de objetos. Streams não mudam a estrutura de dados original. Elas apenas fornecem o resultado de acordo com as operações solicitadas.</p><p>Com o auxílio da operação terminal <code>forEach()</code>, podemos percorrer cada elemento da stream por iteração.</p><p>Por exemplo:</p><pre><code class="language-java">Integer[] intArray = {2,5,46,12,34};

Arrays.stream(intArray).forEach(System.out::print);
// Resultado: 25461234</code></pre><p>Agora, você já sabe como imprimir um array em Java.</p><p>Obrigado pela leitura.</p><p>A imagem de capa é de <a href="https://unsplash.com/@acharki95?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Aziz Acharki</a> e retirada do <a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>.</p><p>Você pode ler outros artigos do autor no <a href="https://medium.com/@mvthanoshan9/object-oriented-programming-principles-in-java-820919dced1a">Medium</a> e no <a href="https://www.freecodecamp.org/news/author/thanoshan/">freeCodeCamp</a> (em inglês).</p><p><strong><strong>Boa programação para você<strong><strong>!</strong></strong></strong></strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Getters e setters em Java explicados ]]>
                </title>
                <description>
                    <![CDATA[ Getters e setters são usados para proteger seus dados, especialmente na criação de classes. Para cada instância de variável, um método getter retorna seu valor, enquanto um método setter o define ou atualiza. Com isso em mente, getters e setters também são conhecidos como métodos de acesso e de modificação, ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/getters-e-setters-em-java-explicados/</link>
                <guid isPermaLink="false">61d6e10e871ec20507fcb16e</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Fri, 07 Jan 2022 21:20:49 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/01/5f9c9d90740569d1a4ca386a.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</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>Getters e setters são usados para proteger seus dados, especialmente na criação de classes.</p><p>Para cada instância de variável, um método getter retorna seu valor, enquanto um método setter o define ou atualiza. Com isso em mente, getters e setters também são conhecidos como métodos de <em><em>acesso</em></em> e de <em><em>m</em>odificação</em>, respectivamente.</p><p>Por convenção, getters começam com a palavra "get" e setters com a palavra "set", seguidos de um nome de variável. Em ambos os casos, a primeira letra do nome da variável será maiúscula:</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>O método getter retorna o valor do atributo. O método setter recebe um parâmetro e o coloca no atributo.</p><p>Quando os métodos getter e setter estiverem definidos, os utilizamos no main:</p><pre><code class="language-java">public static void main(String[] args) {
  Vehicle v1 = new Vehicle();
  v1.setColor("Vermelho");
  System.out.println(v1.getColor());
}

// O resultado é "Vermelho"</code></pre><p>Getters e setters permitem o controle dos valores. Você pode validar o valor dado no setter antes de definir o valor de fato.</p><h3 id="por-que-usar-getters-e-setters"><strong>Por que usar <strong>getters </strong>e<strong> setters?</strong></strong></h3><p>Getters e setters permitem controlar a forma como variáveis importantes são acessadas e atualizadas no seu código. Por exemplo, considere este método 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>Ao usar o método <code>setNumber</code>, você pode se certificar de que o valor de <code>number</code> está sempre entre 1 e 10. Isso é muito melhor do que atualizar a variável <code>number</code> diretamente:</p><pre><code class="language-java">obj.number = 13;</code></pre><p>Se você atualizar <code>number</code> diretamente, você pode vir a causar efeitos colaterais indesejados em outros pontos do seu código. Aqui, definir <code>number</code> com o valor de 13 violaria a restrição que desejamos estabelecer de que o número precisa estar entre 1 e 10.</p><p>Tornar <code>number</code> uma variável privada e usar o método <code>setNumber</code> evita que isso aconteça.</p><p>Por outro lado, a única maneira de ler o valor de <code>number</code> é usando um método getter:</p><pre><code class="language-java">public int getNumber() {
  return this.number;
}</code></pre> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Da string ao int em Java – Como converter uma string em um inteiro ]]>
                </title>
                <description>
                    <![CDATA[ Objetos de string são representados como uma cadeia de caracteres. Se você já trabalhou com o Java Swing, ele tem componentes como o JTextField e o JTextArea, que nós usamos para obter entradas de dados da GUI. Eles carregam nossos dados como strings. Se quisermos fazer uma calculadora simples usando ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/da-string-ao-int-em-java-como-converter-uma-string-em-um-inteiro/</link>
                <guid isPermaLink="false">61504babee833a04f4436896</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Tue, 28 Sep 2021 12:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2021/09/Untitled-design.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</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>Objetos de string são representados como uma cadeia de caracteres.</p><p>Se você já trabalhou com o Java Swing, ele tem componentes como o JTextField e o JTextArea, que nós usamos para obter entradas de dados da GUI. Eles carregam nossos dados como strings.</p><p>Se quisermos fazer uma calculadora simples usando o Swing, precisamos descobrir como converter uma string em um número inteiro. Isso nos leva à pergunta – como podemos converter uma string em um inteiro?</p><p>Em Java, podemos usar <code>Integer.valueOf()</code> e <code>Integer.parseInt()</code> para converter uma string em um número inteiro.</p><h2 id="1-use-integer-parseint-para-converter-uma-string-em-um-n-mero-inteiro"><strong><strong>1. Use Integer.parseInt() </strong></strong>para converter uma string em um número inteiro</h2><p>Este método retorna a string como um <strong>tipo p<strong>rimitiv</strong>o<strong> int</strong></strong>. Se a string não contiver um número inteiro válido, será lançada uma <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html">NumberFormatException</a>.</p><p>Assim, sempre que convertemos uma string em um int, precisamos lidar com essa exceção colocando o código dentro de um bloco de try-catch.</p><p>Vamos considerar um exemplo convertendo uma string em um int usando <code>Integer.parseInt()</code>:</p><pre><code class="language-java">        String str = "25";
        try{
            int number = Integer.parseInt(str);
            System.out.println(number); // resultado = 25
        }
        catch (NumberFormatException ex){
            ex.printStackTrace();
        }</code></pre><p>Vamos tentar quebrar esse código inserindo um número inteiro inválido:</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>Como você pode ver no código acima, tentamos converter <code>25T</code> em um número inteiro. Esta não é uma entrada válida. Portanto, ela deverá lançar uma NumberFormatException.</p><p>Este é o resultado do código acima:</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>Em seguida, vamos ver como converter uma string em um número inteiro usando o método <code>Integer.valueOf()</code>.</p><h2 id="2-use-integer-valueof-para-converter-uma-string-em-um-n-mero-inteiro"><strong><strong>2. Use Integer.valueOf() </strong></strong>para converter uma string em um número inteiro</h2><p>Este método retorna a string como um <strong>objeto de número i<strong>nte</strong>iro</strong>. Se você olhar a <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#valueOf(java.lang.String)">documentação do Java</a>, <code>Integer.valueOf()</code> retorna um objeto de número inteiro equivalente a <code>new Integer(Integer.parseInt(s))</code>.</p><p>Colocaremos nosso código dentro de um bloco de try-catch ao usar esse método. Vejamos um exemplo usando o método <code>Integer.valueOf()</code>:</p><pre><code class="language-java">        String str = "25";
        try{
            Integer number = Integer.valueOf(str);
            System.out.println(number); // resultado = 25
        }
        catch (NumberFormatException ex){
            ex.printStackTrace();
        }</code></pre><p>Agora, vamos tentar quebrar o código acima inserindo um número inteiro inválido:</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>Da mesma maneira que no exemplo anterior, o código acima lançará uma exceção.</p><p>Aqui está o resultado do código acima:</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>Também criaremos um método para verificar se a string informada é numérica ou não antes de usar os métodos mencionados acima.</p><p>Criei um método simples para verificar se a string informada é ou não numérica.</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>O resultado é:</p><pre><code class="language-java">true
true</code></pre><p>O método <code>isNumeric()</code> recebe uma string como argumento. Primeiro, ele verifica se o argumento é <code>null</code> ou não. Depois disso, usamos o método <code>matches()</code> para verificar se ele contém algarismos de 0 a 9 e o caractere de ponto.</p><p>Essa é uma maneira simples de verificar valores numéricos. Você pode escrever ou pesquisar no Google para encontrar expressões regulares mais avançadas que capturem números, dependendo de seu caso.</p><p>É uma prática recomendada verificar se a string informada é numérica ou não antes de tentar convertê-la em um número inteiro.</p><p>Obrigado pelo leitura.</p><p>Imagem da publicação: <a href="https://unsplash.com/@itfeelslikefilm?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">🇸🇮 Janko Ferlič</a>, do <a href="https://unsplash.com/collections/139346/soul-care?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p><p>Entre em contato com o autor do texto pelo <a href="https://mvthanoshan.medium.com/">Medium</a>.</p><p><strong>Feliz programação<strong>!</strong></strong></p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
