惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
www.infosecurity-magazine.com
www.infosecurity-magazine.com
V
Visual Studio Blog
T
The Blog of Author Tim Ferriss
GbyAI
GbyAI
Y
Y Combinator Blog
雷峰网
雷峰网
Last Week in AI
Last Week in AI
Jina AI
Jina AI
月光博客
月光博客
G
Google Developers Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Webroot Blog
Webroot Blog
Google DeepMind News
Google DeepMind News
博客园 - 三生石上(FineUI控件)
Hacker News - Newest:
Hacker News - Newest: "LLM"
N
News | PayPal Newsroom
H
Heimdal Security Blog
Recorded Future
Recorded Future
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
腾讯CDC
AWS News Blog
AWS News Blog
NISL@THU
NISL@THU
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 【当耐特】
P
Privacy International News Feed
I
Intezer
V
Vulnerabilities – Threatpost
The GitHub Blog
The GitHub Blog
L
LINUX DO - 最新话题
S
Schneier on Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
小众软件
小众软件
博客园 - 聂微东
V2EX - 技术
V2EX - 技术
W
WeLiveSecurity
Security Latest
Security Latest
PCI Perspectives
PCI Perspectives
The Hacker News
The Hacker News
T
Threatpost
C
Check Point Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Latest news
Latest news
L
LINUX DO - 热门话题
J
Java Code Geeks
A
Arctic Wolf
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Troy Hunt's Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Coleções Java
Matheus de G · 2026-05-09 · via DEV Community

O Java possui APIs úteis para o desenvolvimento e uma delas é a API Collections. A API de coleções do java é algo que você usará todo o dia, mesmo que não perceba.

Agrupar valores relacionados é algo comum no desenvolvimento, como notas de alunos, eventos que ocorreram em um certo dia ou uma lista de tarefas para serem feitas.

Esse agrupamento pode ser feitos de várias formas e o java collections fornece a API necessária para isso no java.

Array

A forma mais simples de agrupar valores é usando um Array. O array é uma estrutura de dados homogenia, ou seja, todos os valores possuem o mesmo tipo.

O Array deve ter tamanho fixo que pode ser declarado definindo os valores na inicialização ou definindo um tamanho usando new.

public class Main {
    public static void main(String[] args) {
        int[] notas = { 10, 8, 9, 7 };

        String[] tarefas = {
                "Dar like no post",
                "Comentar algo",
                "Compartilhar o post"
        };

        String[] diasDaSemana = new String[7];
        diasDaSemana[0] = "Domingo";
        diasDaSemana[1] = "Segunda-feira";
        diasDaSemana[2] = "Terça-feira";
        diasDaSemana[3] = "Quarta-feira";
        diasDaSemana[4] = "Quinta-feira";
        diasDaSemana[5] = "Sexta-feira";
        diasDaSemana[6] = "Sábado";
    }
}

Enter fullscreen mode Exit fullscreen mode

O array é alocado de forma contígua na memória. Isso significa que os espaços para cada dado no array é seguido um após o outro. O array notas estaria mais ou menos assim na memória.

Array na memória

A desvantagem é que caso não houver um o espaço contíguo na memória o array não conseguiria ser criado.

Memória ocupada

A vantagem disso é permitir um acesso instantâneo O(1) a qualquer valor do array. O programa faz uma conta simples para o acesso aos valores:

endereço = endereço_da_variavel_array + tamanho_do_tipo_de_dado * indice_do_array

Enter fullscreen mode Exit fullscreen mode

Por exemplo, vamos pegar o array notas, o tamanho de um int no java é 4 bytes, o índice de um array inicia em 0 e vamos imaginar que notas está no endereço 0x100 (256 em hexadecimal). Então a conta para acessar seria:

// acessando o índice 0 (primeiro índice)
x = 0x100 + 0x4 * 0x0
x = 0x100 + 0x0
x = 0x100 // 200 em hexadecimal que é o endereço onde está o primeiro valor

Enter fullscreen mode Exit fullscreen mode

E se quisermos o último valor? O último índice é 3 já que os índices vão de 0 até o tamanho do array - 1.

// acessando o índice 3 (último índice)
x = 0x100 + 0x4 * 0x3
x = 0x100 + 0xC
x = 0x10C // 268 em hexadecimal que é o endereço onde está o último valor

Enter fullscreen mode Exit fullscreen mode

Por isso o array é uma ótima estrutura para acessar valores.

Coleções

O array é a forma mais simples de agrupar valores. O java possui uma API completa para isso chamada Java Collections.

Essa API possui várias classes e interfaces para diferentes tipos de agrupamentos de valores e métodos para manipulação desses agrupamentos.

Abaixo temos a hierarquia das interfaces dessa API.

Hierarquia java collections

List

List é uma interface que defini operações para uma coleção de lista de valores, com ordem e índices. Temos duas principais implementações dessa interface, ArrayList e LinkedList.

ArrayList

O ArrayList uma implementação da interface List. Essa classe armazena os dados em um formato de array. O ArrayList pode aumentar ou diminuir o seu tamanho, diferente do array convencional que tem tamanho fixo.

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> linguagens = new ArrayList<>();

        linguagens.add("Java");
        linguagens.add("Python");
        linguagens.add("C++");

        linguagens.remove(1); // Remove "Python"

        linguagens.forEach(System.out::println); // imprimi os elementos
    }
}

Enter fullscreen mode Exit fullscreen mode

O ArrayList resolve o problema de tamanho fixo de um array. Internamente ele cria um array com um tamanho inicial de 10 por padrão.

A medida que você adiciona elementos com o método add() o ArrayList cria um novo array internamente e copia os dados para esse novo array.

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // internamente é um array de tamanho 10: Integer[] notas = new Integer[10];
        List<Integer> notas = new ArrayList<>();

        notas.add(10);
        notas.add(8);
        notas.add(9);
        notas.add(7);

        Integer nota = 6;
        notas.add(nota);

        // remoção por referência ao objeto
        notas.remove(nota); // Remove o objeto nota da lista
        System.out.println(notas); // [10, 8, 9, 7]

        // adiciona mais elementos no ArrayList
        // Internamente o ArrayList cria um novo array com mais capacidade e copia os elementos para ele
        for (int i = 0; i < 10; i++) {
            notas.add(i);
        }

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

Enter fullscreen mode Exit fullscreen mode

LinkedList

O ArrayList resolve o problema de ter um array de tamanho fixo, mas ainda temos o problema de precisar ter espaço contíguo na memória para array, mesmo usando um ArrayList.

Para esse tipo de problema temos uma outra implementação da interface List chamada LinkedList. Essa classe é uma lista encadeada, onde cada valor é um nó da lista que aponta para o nó anterior e posterior. Se usarmos um LinkedList para armazenar aquele array de notas ficaria algo parecido com isso:

Lista encadeada na memória

A desvantagem desse tipo de implementação é que o acesso a um valor é linear O(n). Ou seja, se eu quiser o terceiro valor na lista, eu preciso acessar o primeiro e o segundo elemento até chegar no terceiro.

A vantagem desse tipo de implementação é que adicionar e remove valores é menos custoso já que é apenas necessário mudar o valor dos campos próximo e anterior dos nós o que é uma complexidade linear O(1).

Como LinkedList implementa a interface List podemos continuar com o código anterior e mudar apenas a classe ArrayList para LinkedList.

import java.util.LinkedList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> notas = new LinkedList<>(); // Alterando a implementação para LinkedList

        notas.add(10);
        notas.add(8);
        notas.add(9);
        notas.add(7);

        Integer nota = 6;
        notas.add(nota);

        // remoção por referência ao objeto
        notas.remove(nota); // Remove o objeto nota da lista
        System.out.println(notas); // [10, 8, 9, 7]

        for (int i = 0; i < 10; i++) {
            notas.add(i);
        }

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

Enter fullscreen mode Exit fullscreen mode

Set

O Set é outra interface que pertence ao java collections e representa uma estrutura de conjunto. Os conjuntos guardam elementos sem um índice ou ordem, como fazia com List, e não permite elementos duplicados.

Algumas implementações da interface Set são HashSet, TreeSet e LinkedHashSet.

Hierarquia Set

HashSet

O HashSet implementa a interface Set usando um tabela hash através da classe HashMap. Assim, quando você adiciona um valor ao HashSet ele cria um registro no HashMap interno com a chave sendo o valor que você adicionou e um Object para preencher o valor do HashMap

import java.util.HashSet;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        Set<String> linguagens = new HashSet<>();

        String java = "Java";
        String javascript = "JavaScript";

        // internamente: HashMap: { "Java": Object }
        linguagens.add(java);

        // adicionar o mesmo valor faz apenas recriar a chave no HashMap
        linguagens.add(java);

        // internamente: HashMap: { "Java": Object, "JavaScript": Object }
        linguagens.add(javascript);

        /*
         * internamente:
         * HashMap: {
         * "Java": Object,
         * "C": Object,
         * "Typescript": Object,
         * "JavaScript": Object
         * }
         */
        linguagens.add("Typescript");
        linguagens.add("C");

        System.out.println(linguagens); // [Java, C, Typescript, JavaScript]

        linguagens.remove(javascript); // Remove "JavaScript" do conjunto

        System.out.println(linguagens); // [Java, C, Typescript]
    }
}

Enter fullscreen mode Exit fullscreen mode

Esse tipo de implementação permite um acesso constante O(1) já que acessar um valor na tabela hash é acesso constante.

Note que mesmo adicionando a string "C" por último, ela foi impressa como sendo a segunda. Isso, porque o Set não garante uma ordem dos elementos.

LinkedSet

Essa implementação do Set utiliza uma lista duplamente encadeada para manter a ordem dos elementos e um HashMap para implementar os métodos da interface Set.

import java.util.LinkedHashSet;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        Set<String> linguagens = new LinkedHashSet<>(); // Trocando para LinkedHashSet

        String java = "Java";
        String javascript = "JavaScript";

        /*
         * internamente:
         * HashMap: { "Java": Object }
         * LinkedList: head <-> "Java" <-> tail
         */
        linguagens.add(java);

        // adicionar o mesmo valor faz apenas recriar a chave no HashMap
        linguagens.add(java);

        /*
         * internamente:
         * HashMap: { "Java": Object, "JavaScript": Object }
         * LinkedList: head <-> "Java" <-> "JavaScript" <-> tail
         */
        linguagens.add(javascript);

        /*
         * internamente:
         * HashMap: {
         * "Java": Object,
         * "JavaScript": Object,
         * "Typescript": Object,
         * "C": Object
         * }
         * LinkedList: head <-> "Java" <-> "JavaScript" <-> "Typescript" <-> "C" <-> tail
         */
        linguagens.add("Typescript");
        linguagens.add("C");

        System.out.println(linguagens); // [Java, JavaScript, Typescript, C]

        linguagens.remove(javascript); // Remove "JavaScript" do conjunto

        System.out.println(linguagens); // [Java, Typescript, C]
    }
}

Enter fullscreen mode Exit fullscreen mode

TreeSet

O TreeSet é um implementação da interface NavigableSet que extende o SortedSet que é um interface que extende o Set. O SortedSet são conjuntos ordenados. Internamente o TreeSet usa uma Árvore Rubro-Negra que é uma árvore binária de busca auto balanceada, um tipo de estrutura de dados, para guarda os valores ordenados.

O TreeSet ordena os valores que podem ser comparados, ou seja, que implementam a interface Comparable. Caso o valor não implemente a interface Comparable, pode ser passado um Comparator no construtor do TreeSet para que a classe saiba como ordenar os valores.

A impressão dos valores utiliza o algoritmo de percurso "em ordem" das árvores binárias.

import java.util.Set;
import java.util.TreeSet;

public class Main {
    static record Product(String name, double price) {
    }

    static class ProductCompable implements Comparable<ProductCompable> {
        String name;
        double price;

        public ProductCompable(String name, double price) {
            this.name = name;
            this.price = price;
        }

        @Override
        public int compareTo(ProductCompable other) {
            return Double.compare(this.price, other.price);
        }
    }

    public static void main(String[] args) {
        // Passando um Comparable
        Set<ProductCompable> productSetComparable = new TreeSet<>();

        // Passando um Comparator através de uma expressão lambda para ordenar
        Set<Product> productSet = new TreeSet<>((p1, p2) -> Double.compare(p1.price, p2.price));

        productSet.add(new Product("Laptop", 999.99));
        productSet.add(new Product("Smartphone", 499.99));
        productSet.add(new Product("Tablet", 299.99));
        productSet.add(new Product("Headphones", 199.99));
        productSet.add(new Product("Smartwatch", 199.50));
        productSet.add(new Product("Camera", 599.99));

        // Imprime os produtos usando o percurso "em ordem" de árvores binárias de busca
        productSet.forEach(System.out::println);
        /* 
         Product[name=Smartwatch, price=199.5]
         Product[name=Headphones, price=199.99]
         Product[name=Tablet, price=299.99]
         Product[name=Smartphone, price=499.99]
         Product[name=Camera, price=599.99]
         Product[name=Laptop, price=999.99]
        */
    }
}

Enter fullscreen mode Exit fullscreen mode

A árvore gerada pelo código acima seria algo assim:

Árvore Rubro-Negra

Queue e Deque

Outra interface que pertence ao Java Collection é a Queue. Essa interface representa uma estrutura de fila.

Filas tem a propriedade de FIFO (Fisrt In Last Out), o primeiro elemento a entrar na fila será sempre o primeiro a sair dela.

Fila

A Deque é um tipo especialmente de fila, uma "fila de duas pontas". Ela permite inserir e excluir da fila pelo inicio (head) ou final (tail).

Deque adiciona métodos com sufixo Fist e Last para manipular a fila como addFirst() e addLast.

Algumas classes que implementam a interface Queue e Deque são LinkedList, PriorityQueue e ArrayDeque.

Hierarquia Queue

PriorityQueue

A PriorityQueue é uma fila de prioridade. Ela usa um array para armazenar os valores, mas ela também usa a interface Comparable para definir a prioridade dos elementos adicionados.

Caso a classe que a PriorityQueue guarda não implemente Comparable, pode ser passado um Comparator no construtor para definir o critério de prioridade que será usado.

import java.util.PriorityQueue;
import java.util.Queue;

public class Main {
    record Person(String name, int age) {
    }

    public static void main(String[] args) {
        Person jose = new Person("José", 30);
        Person zezinho = new Person("Zezinho", 25);
        Person seuZe = new Person("Seu Zé", 65);
        Person maria = new Person("Maria", 70);

        // Prioridade de atendimento: pessoas mais velhas têm prioridade
        Queue<Person> atendimento = new PriorityQueue<>((p1, p2) -> Integer.compare(p2.age(), p1.age()));

        // Adicionando a fila. Sempre no final da fila
        atendimento.add(jose);
        atendimento.add(maria);
        atendimento.add(zezinho);
        atendimento.add(seuZe);

        System.out.println("Fila de atendimento: " + atendimento.stream().map(Person::name).toList());
        // Fila de atendimento: [Maria, Seu Zé, Zezinho, José]

        // Removendo o primeiro da fila. Sempre o primeiro da fila
        Person atendido = atendimento.poll();
        System.out.println("Atendido: " + atendido.name()); // Atendido: Maria

        System.out.println("Fila após o atendimento: " + atendimento.stream().map(Person::name).toList());
        // Fila após o atendimento: [Seu Zé, Zezinho, José]

        // Verificando o primeiro da fila sem removê-lo
        System.out.println("Primeiro da fila: " + atendimento.peek().name()); // Primeiro da fila: Seu Zé
    }
}

Enter fullscreen mode Exit fullscreen mode

LinkedList

Além de implementar a interface List, o LinkedList implementa a interface Deque. Como uma lista encadeada tem um referência para o inicio (head) e para o final (tail) da lista, para funcionar como uma fila dupla é só usar essas referências para inserir e remover no final e remover no inicio da lista encadeada.

Lista encadeada

import java.util.Deque;
import java.util.LinkedList;

public class Main {
    record Person(String name, int age) {
    }

    public static void main(String[] args) {
        Person jose = new Person("José", 30);
        Person zezinho = new Person("Zezinho", 25);
        Person seuZe = new Person("Seu Zé", 65);
        Person maria = new Person("Maria", 70);

        Deque<Person> atendimento = new LinkedList<>();

        // Adicionando no final da fila
        atendimento.add(jose);
        atendimento.add(zezinho);

        // Adicionando no início da fila
        atendimento.addFirst(seuZe);
        atendimento.addFirst(maria);

        System.out.println("Fila de atendimento: " + atendimento.stream().map(Person::name).toList());
        // Fila de atendimento: [Maria, Seu Zé, José, Zezinho]

        // Removendo o primeiro da fila
        Person atendido = atendimento.poll();
        System.out.println("Atendido: " + atendido.name());
        // Atendido: Maria

        // Removendo o último da fila
        Person person = atendimento.pollLast();
        System.out.println("Desistiu da fila: " + person.name());
        // Desistiu da fila: Zezinho

        System.out.println("Fila de atendimento: " + atendimento.stream().map(Person::name).toList());
        // Fila de atendimento: [Seu Zé, José]

        // Verificando o primeiro da fila sem removê-lo
        System.out.println("Primeiro da fila: " + atendimento.peek().name());
        // Primeiro da fila: Seu Zé
    }
}

Enter fullscreen mode Exit fullscreen mode

ArrayDeque

O ArrayDeque é uma classe que implementa o Deque. Usa internamente um array circular de tamanho 16 para armazenar os valores.

Internamente, o ArrayDeque guarda o índice do inicio (head) e do fim (tail) do array circular. A medida que adicionar valores no fim com o método add(), por exemplo, a classe altera o valor do tail. E quando adicionar no inicio com o método addFist(), por exemplo, a classe altera o head.

Array circular

Quando não há mais espaço no array, um novo array com mais capacidade é criado e os dados são copiados para esse novo array

import java.util.ArrayDeque;
import java.util.Deque;

public class Main {
    public static void main(String[] args) {
        Deque<Integer> deque = new ArrayDeque<>();

        // adiciona no fim e altera o valor de tail
        deque.add(3);
        deque.add(22);
        deque.addLast(10);

        // adiciona no início e altera o valor de head
        deque.addFirst(15);

        System.out.println(deque);
        // [15, 3, 22, 10]

        // Cria um novo array com mais capacidade e copia os elementos do array antigo
        // para o novo array
        for (int i = 0; i < 100; i++) {
            deque.add(i);
        }

    }
}

Enter fullscreen mode Exit fullscreen mode

Iterable e Collection

Subindo ao nível mais genérico, temos as interfaces Collection e Iterable.

O Collection é uma coleção genérica. Todas as classes do Java Collection implementam essa interface. Se, por exemplo, você precisa modificar qualquer tipo de coleção do Java Collection através de um método, você pode usar um Collection como argumento.

O Iterable é um coleção objetos que pode ser ser lida e ser percorrida um objecto por vez. Se, por exemplo, você precisa acessar cada valor de uma coleção de objetos usando um método você pode receber como argumento um Iterable. Cada classe tem uma forma de guardar os valores e por isso cada uma tem sua implementação de Iterable para pode ser navegável de acordo com sua implementação usando um Iterator, um objeto que sabe navegar por um Iterable.

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        Queue<Integer> queue = new ArrayDeque<>();
        Deque<Integer> deque = new LinkedList<>();
        Set<Integer> set = new HashSet<>();

        modifyCollection(list);
        modifyCollection(queue);
        modifyCollection(deque);
        modifyCollection(set);

        System.out.print("List:");
        printCollection(list); // List: 42

        System.out.print("Queue:");
        printCollection(queue); // Queue: 42

        System.out.print("Deque:");
        printCollection(deque); // Deque: 42

        System.out.print("Set:");
        printCollection(set); // Set: 42
    }

    static void printCollection(Iterable<Integer> iterable) {
        // Iterables podem ser usados nesse tipo de for
        for (Integer element : iterable) {
            System.out.println(element);
        }
    }

    static void modifyCollection(Collection<Integer> collection) {
        if (collection.isEmpty()) {
            collection.add(42);
        } else {
            collection.remove(collection.iterator().next());
        }
    }
}

Enter fullscreen mode Exit fullscreen mode