0Pricing
Java Academy · Aula

Submapas e Visões de Intervalos

Extraia visões com subMap, headMap e tailMap para consultas por intervalo em mapas ordenados.

Submapas e Visões de Intervalos é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.

Visualizações de intervalos em TreeMap

subMap, headMap e tailMap de TreeMap retornam visualizações apoiadas pelo mapa — elas refletem as alterações no mapa subjacente e vice-versa. As alterações feitas por meio da visualização são refletidas no mapa original.

TreeMap<Integer, String> map = new TreeMap<>();
for (int i = 1; i <= 10; i++) map.put(i * 10, "item" + i);

var view = map.subMap(30, 70); // [30, 70)
System.out.println(view); // {30=item3, 40=item4, 50=item5, 60=item6}

map.put(45, "new"); // also visible through view!
System.out.println(view.containsKey(45)); // true

headMap: chaves abaixo de um limite

headMap(toKey) retorna todas as entradas com chaves estritamente menores que toKey. Use a variante inclusiva headMap(toKey, true) para incluir o limite.

TreeMap<String, Integer> words = new TreeMap<>();
"banana cherry apple date elderberry".chars()
    .mapToObj(c -> String.valueOf((char)c)).distinct()
    .forEach(w -> words.put(w, w.length()));
// Actually let's use real words:
TreeMap<String, Integer> wc = new TreeMap<>();
wc.put("apple",5); wc.put("banana",6); wc.put("cherry",6); wc.put("date",4);

System.out.println(wc.headMap("cherry")); // {apple=5, banana=6}

tailMap: chaves a partir de um limite

tailMap(fromKey) retorna todas as entradas com chaves ≥ fromKey.

TreeMap<Integer, String> grades = new TreeMap<>();
grades.put(50,"F"); grades.put(60,"D"); grades.put(70,"C"); grades.put(80,"B"); grades.put(90,"A");

// All passing grades (>= 60)
var passing = grades.tailMap(60);
System.out.println(passing); // {60=D, 70=C, 80=B, 90=A}

subMap com limites inclusivos

O subMap(from, fromInclusive, to, toInclusive) com quatro argumentos oferece controle total sobre a inclusão dos limites:

TreeMap<Integer, String> map = new TreeMap<>();
for (int i = 10; i <= 100; i += 10) map.put(i, "v"+i);

// [30, 60] — both inclusive
System.out.println(map.subMap(30, true, 60, true));
// {30=v30, 40=v40, 50=v50, 60=v60}

// (30, 60) — both exclusive
System.out.println(map.subMap(30, false, 60, false));
// {40=v40, 50=v50}

Modificando por meio de uma visualização

As operações put/remove em uma visualização de subMap são refletidas no mapa original (e vice-versa). Tentar inserir uma chave fora do intervalo da visualização lança uma exceção.

TreeMap<Integer, String> map = new TreeMap<>();
for (int i = 1; i <= 5; i++) map.put(i * 10, "v" + i);

var view = map.subMap(20, 40); // [20, 40)
view.remove(20); // removes from both view and original map
System.out.println(map.containsKey(20)); // false

// This would throw IllegalArgumentException:
// view.put(50, "out of range");

Caso de uso: consulta de intervalo de registros

Recupere todas as entradas de registro entre duas marcas de tempo usando uma visualização de intervalo de TreeMap:

import java.time.*;
TreeMap<LocalDateTime, String> logs = new TreeMap<>();
logs.put(LocalDateTime.of(2024,1,1,8,0), "Server start");
logs.put(LocalDateTime.of(2024,1,1,10,0), "Request spike");
logs.put(LocalDateTime.of(2024,1,1,14,0), "Maintenance");
logs.put(LocalDateTime.of(2024,1,1,18,0), "Server stop");

var morning = logs.subMap(
    LocalDateTime.of(2024,1,1,8,0), true,
    LocalDateTime.of(2024,1,1,12,0), false
);
morning.forEach((t,m) -> System.out.println(t+" : "+m));

Caso de uso: busca por intervalo de preços

Encontre todos os produtos em um intervalo de preços usando as chaves de TreeMap como preços:

TreeMap<Double, String> products = new TreeMap<>();
products.put(9.99, "Pen");
products.put(24.99, "Book");
products.put(49.99, "Headphones");
products.put(299.99, "Tablet");

double min = 10.0, max = 100.0;
var affordable = products.subMap(min, true, max, true);
affordable.forEach((p,n) -> System.out.println(n+" $"+p));
// Book $24.99, Headphones $49.99

subMap descendente

Encadeie descendingMap() em uma visualização para navegar em ordem inversa:

TreeMap<Integer, String> map = new TreeMap<>();
for (int i = 10; i <= 100; i += 10) map.put(i, "v"+i);

// Get [40, 80] in descending order
map.subMap(40, true, 80, true)
   .descendingMap()
   .forEach((k,v) -> System.out.println(k + "=" + v));
// 80=v80, 70=v70, 60=v60, 50=v50, 40=v40

Interface NavigableMap

NavigableMap estende SortedMap e adiciona navegação pelas chaves ceiling/floor/higher/lower, além de visualizações descendentes. TreeMap é a implementação mais comum; ConcurrentSkipListMap é a alternativa segura para uso com várias threads.

Desempenho das visualizações

As operações em uma visualização de submapa (get, put, containsKey) têm a mesma complexidade O(log n) da TreeMap subjacente. A criação da visualização em si é O(1) — nenhuma cópia é feita. As varreduras de intervalo sobre n chaves na visualização são O(log N + n), onde N é o tamanho total do mapa.

Armadilha: visualizações desatualizadas

Como as visualizações são apoiadas pelo mapa original, uma visualização pode ficar vazia ou lançar uma exceção se o mapa original for limpo. Sempre documente que as visualizações são dinâmicas e não as mantenha além do ciclo de vida pretendido.

TreeMap<Integer, String> map = new TreeMap<>();
map.put(10, "a"); map.put(20, "b"); map.put(30, "c");

var view = map.subMap(10, 30);
map.clear(); // view becomes empty
System.out.println(view.size()); // 0 — but no exception

Verificação rápida

Você chama map.subMap(30, false, 70, true) em uma TreeMap com as chaves {10,20,30,40,50,60,70,80}. Quais chaves são incluídas no resultado?

Recapitulação: submapas e visualizações de intervalos

Principais conclusões:

  • subMap, headMap, tailMap retornam visualizações dinâmicas apoiadas pelo mapa — sem cópia
  • As alterações na visualização se refletem no mapa original e vice-versa
  • subMap(from, fromInclusive, to, toInclusive) com quatro argumentos oferece controle total dos limites
  • Operações put fora do intervalo por meio de uma visualização lançam IllegalArgumentException
  • Complexidade da varredura de intervalo: O(log N + n)

Perguntas Frequentes

A aula “Submapas e Visões de Intervalos” é grátis?

Sim — o texto completo de “Submapas e Visões de Intervalos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.

O que vou aprender em “Submapas e Visões de Intervalos”?

Extraia visões com subMap, headMap e tailMap para consultas por intervalo em mapas ordenados. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Java Academy?

Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “Submapas e Visões de Intervalos”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Java Academy?

Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. TreeMap: Pares Ordenados de Chave e Valor
  2. Submapas e Visões de Intervalos
  3. TreeSet e NavigableSet
  4. Ordenação Personalizada em Coleções Tree
← Voltar para Java Academy