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)); // trueheadMap: 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.99subMap 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=v40Interface 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 exceptionVerificaçã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
- TreeMap: Pares Ordenados de Chave e Valor
- Submapas e Visões de Intervalos
- TreeSet e NavigableSet
- Ordenação Personalizada em Coleções Tree