Pular para o conteúdo principal
ProdutosFerramentas de desktopTASTECADVisualização de desenhosTASTEFILESGerenciamento de arquivosTASTEFTPTransferência de arquivosTASTESSHEspaço de trabalho remotoTASTEZIPCompactação e extraçãoFerramentas para desenvolvedoresTASTECODEAmbiente de desenvolvimento integrado para RustTASTESTUDIOAmbiente integrado de desenvolvimento e testesTASTEETLIntegração de dados (ETL)ServidoresTASTEREMOTEServidor de área de trabalho remotaTASTEGEOServidor geoespacialTASTEMAILEspaço de trabalho de e-mailComeçarDownloadsDocumentaçãoComprarTodos os produtos
Marketplace
Notícias
TecnologiaNotíciasNotícias de desenvolvimento de hojeDocumentaçãoLinguagens de programaçãoRustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDartFrameworks de front-end webNext.jsReactVue.js · NuxtSvelteKitAngularFrameworks de servidorSpring BootDjangoFastAPIASP.NET CoreNestJS · ExpressFrameworks de apps e desktopTauriFlutterReact NativeElectronAlgoritmosFundamentos de algoritmosAlgoritmos essenciaisAlgoritmos avançadosAlgoritmos práticos
ComunidadeProjetosRegistros de desenvolvimentoPromptsProblemas de ferramentas de IAVitrineGuia da comunidade
ColaboreTransferência técnicaConstrução de siteConstrução de app de desktopPipeline de lançamento e pagamentoParceiro de vendasContato
ServiçosÁrea de trabalho remotaPacotes de instalação sob medida
TASTEDEV
Produtos

Ferramentas de desktop

TASTECADDesenhos complexos, abertos com levezaTASTEFILESSó os arquivos de que você precisa, o mais rápido possívelTASTEFTPO caminho mais organizado para seus arquivosTASTESSHEntre você e o servidor, uma conexão mais sólidaTASTEZIPCompacte mais rápido, extraia com mais segurança

Ferramentas para desenvolvedores

TASTECODEEdite, compile, depure e teste apps Rust em uma única janelaTASTESTUDIODa edição aos testes remotos e às correções com IA aprovadasTASTEETLMova dados de olho nos valores

Servidores

TASTEREMOTEUma área de trabalho remota rodando no seu próprio servidorTASTEGEOUm servidor geoespacial compatível com o GeoServer, reconstruído em RustTASTEMAILRetome o controle do seu e-mail

Começar

DownloadsVersões mais recentes de cada produtoDocsComo usar cada produtoComprarAssinaturas e licenças perpétuasTodos os produtosTodos os produtos de relance
Todos os produtos
MarketplaceNotícias
Tecnologia

Notícias

Notícias de desenvolvimento de hojeAnúncios oficiais de linguagens, frameworks, GitHub e IADocumentaçãoGuias de linguagens, frameworks e algoritmos

Linguagens de programação

RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDart

Frameworks

Frameworks de front-end webNext.jsReactVue.js · NuxtSvelteKitAngular
Frameworks de servidorSpring BootDjangoFastAPIASP.NET CoreNestJS · Express
Frameworks de apps e desktopTauriFlutterReact NativeElectron

Algoritmos

Fundamentos de algoritmosAnálise de complexidade · Ordenação · Busca · Estruturas de dados básicas · Árvores e heapsAlgoritmos essenciaisBusca em grafos · Caminho mínimo e árvore geradora mínima · Programação dinâmica · Algoritmos gulosos · Divisão e conquista · BacktrackingAlgoritmos avançadosAlgoritmos de strings · Matemática e teoria dos números · Manipulação de bits · Árvores de segmentos · Union-FindAlgoritmos práticosEstratégia para entrevistas de código · Cache LRU · Limitação de taxa · Hashing consistente
Toda a documentação de desenvolvimento
Comunidade
ProjetosDescubra criadores e trabalhosRegistros de desenvolvimentoDecisões e aprendizadosPromptsInstruções reutilizáveisProblemas de ferramentas de IAProblemas e contornos de Claude, Codex, GeminiVitrineResultados concluídosGuia da comunidadeComo construímos em aberto
Colabore
Transferência técnicaApps nativos em Rust e eguiConstrução de site10 idiomas, contas, documentação e downloadsConstrução de app de desktopRust e egui, sem WebViewPipeline de lançamento e pagamentoAssinatura, MSI, deb, rpm, AppImage, hashesParceiro de vendasRecomende e ganhe 30%ContatoDesenvolvimento, parcerias e investimento
Serviços
Área de trabalho remotaAcesse seu computador pelo navegadorPacotes de instalação sob medidaSó o necessário, configurações pré-carregadas
Comprar
PT
한국어EnglishDeutschEspañolFrançaisItalianoPortuguês (Brasil)日本語简体中文繁體中文
Entrar
Entrar
TASTEDEV

De pequenas ferramentas a um desenvolvimento melhor.

support@tastedev.netApoiar TASTEDEV
ProdutosLinha de produtosComprarDocsDownloadsMarketplaceSuporte
ComunidadeProjetosRegistros de desenvolvimentoPromptsProblemas de ferramentas de IAVitrine
PolíticasPolítica de privacidadeTermos de usoTermos de assinaturaReembolsoDiretrizes da comunidade
ContaEntrarCriar conta
Visitantes
Hoje
012345678901234567890123456789012345678901234567890123456789
Ontem
012345678901234567890123456789012345678901234567890123456789
Visualizações totais
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
Empresa
GXSOFT
Representante
CHOI YOUNG GU
Número de registro comercial
853-44-00368
Endereço
9F V24, 351 Gyeongin-ro, Michuhol-gu, Incheon, Republic of Korea
Telefone
+82-10-4404-1523
E-mail
whitecalvin@tastedev.net
Responsável pela privacidade
CHOI YOUNG GU

© 2026 TASTEDEVAs informações dos produtos se baseiam em fontes de desenvolvimento verificadas.Lançado · em melhoria

Documentação de Java
Java
Getting StartedSyntax BasicsTypes and DataModules and PackagesErrors and TestingKey Concepts
Discussões

Guia de Java · 6/6

Key Concepts

Por enquanto, este capítulo está disponível apenas em inglês.

This chapter covers the tools modern Java code leans on every day: lambdas, streams, Optional, and the basics of running work concurrently.

Lambdas and functional interfaces

An interface with exactly one abstract method is a functional interface, and a lambda is a compact way to implement one. When an existing method already does the job, pass a method reference such as Integer::parseInt instead. The java.util.function package defines the common shapes:

InterfaceMethodTypical use
Function<T, R>R apply(T t)Transform a value
Predicate<T>boolean test(T t)Test a condition
Supplier<T>T get()Produce a value on demand
Consumer<T>void accept(T t)Act on a value
import java.util.function.*;

Function<String, Integer> length = s -> s.length();
Predicate<String> isEmpty = String::isEmpty;
Supplier<java.util.List<String>> newList = java.util.ArrayList::new;
Consumer<String> printer = System.out::println;

Predicate<String> notEmpty = isEmpty.negate();
Function<String, Integer> lengthPlusOne = length.andThen(n -> n + 1);

printer.accept("len = " + lengthPlusOne.apply("java")); // len = 5

Lambdas can capture only local variables that are never reassigned (effectively final). Annotate your own functional interfaces with @FunctionalInterface so the compiler checks them.

Streams

A stream is a pipeline: take a source such as a collection, chain intermediate operations like filter, map, and sorted, then finish with a terminal operation like toList, count, or collect. Nothing runs until the terminal operation, and the source is left untouched.

import java.util.*;
import java.util.stream.*;

record Employee(String name, String team, int salary) {}

List<Employee> staff = List.of(
        new Employee("Kim", "dev", 5200),
        new Employee("Lee", "dev", 6100),
        new Employee("Park", "ops", 4800));

List<String> highPaid = staff.stream()
        .filter(e -> e.salary() >= 5000)
        .map(Employee::name)
        .sorted()
        .toList(); // [Kim, Lee]

Map<String, Double> avgByTeam = staff.stream()
        .collect(Collectors.groupingBy(Employee::team,
                Collectors.averagingInt(Employee::salary)));

int total = staff.stream().mapToInt(Employee::salary).sum();
Dúvidas sobre este capítulo?
Capítulo anteriorErrors and Testing

Primitive streams like IntStream avoid boxing when you sum or average numbers. A stream can be consumed only once, and a plain for loop is still the clearer choice for simple iteration or early exits.

Optional

Optional<T> puts the possibility of "no value" into the type. It is meant mostly for return values, so callers are pushed to handle the empty case. Prefer map, orElse, orElseThrow, and ifPresent over calling get() blindly.

import java.util.Optional;

static Optional<Employee> findByName(List<Employee> list, String name) {
    return list.stream()
            .filter(e -> e.name().equals(name))
            .findFirst();
}

String team = findByName(staff, "Lee")
        .map(Employee::team)
        .orElse("unknown"); // dev

findByName(staff, "Choi").ifPresentOrElse(
        e -> System.out.println(e.team()),
        () -> System.out.println("not found"));

Employee lee = findByName(staff, "Lee")
        .orElseThrow(() -> new IllegalStateException("Lee missing"));

Avoid Optional for fields, parameters, and collection elements; an empty collection already means "nothing here".

Concurrency basics

Java has had threads since the beginning, but you rarely create them yourself. Submit tasks to an ExecutorService instead: submit returns a Future, and get() blocks until its result is ready.

import java.util.*;
import java.util.concurrent.*;

static int slowSquare(int n) throws InterruptedException {
    Thread.sleep(100); // simulate slow work
    return n * n;
}

public static void main(String[] args) throws Exception {
    try (ExecutorService pool = Executors.newFixedThreadPool(4)) {
        List<Future<Integer>> futures = new ArrayList<>();
        for (int i = 1; i <= 5; i++) {
            int n = i;
            futures.add(pool.submit(() -> slowSquare(n)));
        }
        int sum = 0;
        for (Future<Integer> f : futures) sum += f.get();
        System.out.println("sum = " + sum); // 55
    } // close() waits for running tasks, then shuts down
}

Recent JDKs add virtual threads: lightweight threads scheduled by the JVM, cheap enough to use one per task. They suit servers that mostly wait on I/O, and the code stays ordinary blocking code; only the executor changes.

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    for (int i = 0; i < 10_000; i++) {
        int id = i;
        executor.submit(() -> {
            Thread.sleep(50); // blocking is cheap here
            return id;
        });
    }
}

When threads share mutable data, use thread-safe types such as ConcurrentHashMap and AtomicInteger, or guard access with synchronized. Sharing immutable records avoids most such problems.

Summary

  • Lambdas and method references implement functional interfaces concisely.
  • Streams transform data declaratively with filter, map, and collect.
  • Optional marks a possibly missing return value; unwrap it with map or orElse.
  • Give concurrent work to an ExecutorService, and consider virtual threads for I/O-heavy workloads.

Official resources for going further:

  • Learn Java (dev.java): the official learning path
  • Java SE Documentation: API references and tool guides
  • The Java Language Specification: the formal specification
  • OpenJDK: JDK development and JEPs
  • JUnit User Guide: the testing framework
  • Maven and Gradle: build tools

0 comentários

Principais comentáriosMais recentes primeiro

Fazer login · Faça login para deixar um comentário.