001 /* 002 * Copyright (C) 2010 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 005 * in compliance with the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License 010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 011 * or implied. See the License for the specific language governing permissions and limitations under 012 * the License. 013 */ 014 015 package com.google.common.collect; 016 017 import static com.google.common.base.Preconditions.checkArgument; 018 import static com.google.common.base.Preconditions.checkNotNull; 019 020 import com.google.common.annotations.Beta; 021 import com.google.common.annotations.GwtCompatible; 022 import com.google.common.annotations.GwtIncompatible; 023 024 import java.util.NoSuchElementException; 025 026 /** 027 * A sorted set of contiguous values in a given {@link DiscreteDomain}. 028 * 029 * @author Gregory Kick 030 * @since 10.0 031 */ 032 @Beta 033 @GwtCompatible(emulated = true) 034 @SuppressWarnings("unchecked") // allow ungenerified Comparable types 035 public abstract class ContiguousSet<C extends Comparable> extends ImmutableSortedSet<C> { 036 final DiscreteDomain<C> domain; 037 038 ContiguousSet(DiscreteDomain<C> domain) { 039 super(Ordering.natural()); 040 this.domain = domain; 041 } 042 043 @Override public ContiguousSet<C> headSet(C toElement) { 044 return headSetImpl(checkNotNull(toElement), false); 045 } 046 047 /** 048 * @since 12.0 049 */ 050 @GwtIncompatible("NavigableSet") 051 @Override public ContiguousSet<C> headSet(C toElement, boolean inclusive) { 052 return headSetImpl(checkNotNull(toElement), inclusive); 053 } 054 055 @Override public ContiguousSet<C> subSet(C fromElement, C toElement) { 056 checkNotNull(fromElement); 057 checkNotNull(toElement); 058 checkArgument(comparator().compare(fromElement, toElement) <= 0); 059 return subSetImpl(fromElement, true, toElement, false); 060 } 061 062 /** 063 * @since 12.0 064 */ 065 @GwtIncompatible("NavigableSet") 066 @Override public ContiguousSet<C> subSet(C fromElement, boolean fromInclusive, C toElement, 067 boolean toInclusive) { 068 checkNotNull(fromElement); 069 checkNotNull(toElement); 070 checkArgument(comparator().compare(fromElement, toElement) <= 0); 071 return subSetImpl(fromElement, fromInclusive, toElement, toInclusive); 072 } 073 074 @Override public ContiguousSet<C> tailSet(C fromElement) { 075 return tailSetImpl(checkNotNull(fromElement), true); 076 } 077 078 /** 079 * @since 12.0 080 */ 081 @GwtIncompatible("NavigableSet") 082 @Override public ContiguousSet<C> tailSet(C fromElement, boolean inclusive) { 083 return tailSetImpl(checkNotNull(fromElement), inclusive); 084 } 085 086 /* 087 * These methods perform most headSet, subSet, and tailSet logic, besides parameter validation. 088 */ 089 /*@Override*/ abstract ContiguousSet<C> headSetImpl(C toElement, boolean inclusive); 090 091 /*@Override*/ abstract ContiguousSet<C> subSetImpl(C fromElement, boolean fromInclusive, 092 C toElement, boolean toInclusive); 093 094 /*@Override*/ abstract ContiguousSet<C> tailSetImpl(C fromElement, boolean inclusive); 095 096 /** 097 * Returns the set of values that are contained in both this set and the other. 098 * 099 * <p>This method should always be used instead of 100 * {@link Sets#intersection} for {@link ContiguousSet} instances. 101 */ 102 public abstract ContiguousSet<C> intersection(ContiguousSet<C> other); 103 104 /** 105 * Returns a range, closed on both ends, whose endpoints are the minimum and maximum values 106 * contained in this set. This is equivalent to {@code range(CLOSED, CLOSED)}. 107 * 108 * @throws NoSuchElementException if this set is empty 109 */ 110 public abstract Range<C> range(); 111 112 /** 113 * Returns the minimal range with the given boundary types for which all values in this set are 114 * {@linkplain Range#contains(Comparable) contained} within the range. 115 * 116 * <p>Note that this method will return ranges with unbounded endpoints if {@link BoundType#OPEN} 117 * is requested for a domain minimum or maximum. For example, if {@code set} was created from the 118 * range {@code [1..Integer.MAX_VALUE]} then {@code set.range(CLOSED, OPEN)} must return 119 * {@code [1..∞)}. 120 * 121 * @throws NoSuchElementException if this set is empty 122 */ 123 public abstract Range<C> range(BoundType lowerBoundType, BoundType upperBoundType); 124 125 /** Returns a short-hand representation of the contents such as {@code "[1..100]"}. */ 126 @Override public String toString() { 127 return range().toString(); 128 } 129 }