aboutsummaryrefslogtreecommitdiffstats
path: root/guava/src/com/google/common/collect/RangeMap.java
blob: ba42985dc8adbb2e0445a655e40772c020251bfb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * Copyright (C) 2012 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.common.collect;

import com.google.common.annotations.Beta;

import java.util.Map;

import javax.annotation.Nullable;

/**
 * A mapping from disjoint nonempty ranges to non-null values. Queries look up the value
 * associated with the range (if any) that contains a specified key.
 *
 * <p>In contrast to {@link RangeSet}, no "coalescing" is done of {@linkplain
 * Range#isConnected(Range) connected} ranges, even if they are mapped to the same value.
 *
 * @author Louis Wasserman
 * @since 14.0
 */
@Beta
public interface RangeMap<K extends Comparable, V> {
  /**
   * Returns the value associated with the specified key, or {@code null} if there is no
   * such value.
   *
   * <p>Specifically, if any range in this range map contains the specified key, the value
   * associated with that range is returned.
   */
  @Nullable
  V get(K key);

  /**
   * Returns the range containing this key and its associated value, if such a range is present
   * in the range map, or {@code null} otherwise.
   */
  @Nullable
  Map.Entry<Range<K>, V> getEntry(K key);

  /**
   * Returns the minimal range {@linkplain Range#encloses(Range) enclosing} the ranges
   * in this {@code RangeMap}.
   *
   * @throws NoSuchElementException if this range map is empty
   */
  Range<K> span();

  /**
   * Maps a range to a specified value (optional operation).
   *
   * <p>Specifically, after a call to {@code put(range, value)}, if
   * {@link Range#contains(Comparable) range.contains(k)}, then {@link #get(Comparable) get(k)}
   * will return {@code value}.
   *
   * <p>If {@code range} {@linkplain Range#isEmpty() is empty}, then this is a no-op.
   */
  void put(Range<K> range, V value);

  /**
   * Puts all the associations from {@code rangeMap} into this range map (optional operation).
   */
  void putAll(RangeMap<K, V> rangeMap);

  /**
   * Removes all associations from this range map (optional operation).
   */
  void clear();

  /**
   * Removes all associations from this range map in the specified range (optional operation).
   *
   * <p>If {@code !range.contains(k)}, {@link #get(Comparable) get(k)} will return the same result
   * before and after a call to {@code remove(range)}.  If {@code range.contains(k)}, then
   * after a call to {@code remove(range)}, {@code get(k)} will return {@code null}.
   */
  void remove(Range<K> range);

  /**
   * Returns a view of this range map as an unmodifiable {@code Map<Range<K>, V>}.
   * Modifications to this range map are guaranteed to read through to the returned {@code Map}.
   *
   * <p>It is guaranteed that no empty ranges will be in the returned {@code Map}.
   */
  Map<Range<K>, V> asMapOfRanges();
  
  /**
   * Returns a view of the part of this range map that intersects with {@code range}.
   * 
   * <p>For example, if {@code rangeMap} had the entries 
   * {@code [1, 5] => "foo", (6, 8) => "bar", (10, \u2025) => "baz"}
   * then {@code rangeMap.subRangeMap(Range.open(3, 12))} would return a range map
   * with the entries {@code (3, 5) => "foo", (6, 8) => "bar", (10, 12) => "baz"}.
   * 
   * <p>The returned range map supports all optional operations that this range map supports,
   * except for {@code asMapOfRanges().iterator().remove()}.
   * 
   * <p>The returned range map will throw an {@link IllegalArgumentException} on an attempt to 
   * insert a range not {@linkplain Range#encloses(Range) enclosed} by {@code range}. 
   */
  RangeMap<K, V> subRangeMap(Range<K> range);

  /**
   * Returns {@code true} if {@code obj} is another {@code RangeMap} that has an equivalent
   * {@link #asMapOfRanges()}.
   */
  @Override
  boolean equals(@Nullable Object o);

  /**
   * Returns {@code asMapOfRanges().hashCode()}.
   */
  @Override
  int hashCode();

  /**
   * Returns a readable string representation of this range map.
   */
  @Override
  String toString();
}