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
|
// Copyright 2014 Google Inc. All rights reserved.
//
// 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.devtools.build.lib.collect.nestedset;
import com.google.common.base.Joiner;
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
/**
* A list-like iterable that supports efficient nesting.
*
* @see NestedSetBuilder
*/
public abstract class NestedSet<E> implements Iterable<E>, Serializable {
NestedSet() {}
/**
* Returns the ordering of this nested set.
*/
public abstract Order getOrder();
/**
* Returns a collection of elements added to this specific set in an implementation-specified
* order.
*
* <p>Elements from subsets are not taken into account.
*
* <p>The reason for using Object[] instead of E[] is that when we build the NestedSet we
* would need to have access to the specific class that E represents in order to create an E
* array. Since this method is only designed to be used internally it is fine to keep it as
* Object[].
*
* <p>Callers of this method should only consume the objects and not modify the array.
*/
abstract Object[] directMembers();
/**
* Returns the collection of sets included as subsets in this set.
*
* <p>Callers of this method should only consume the objects and not modify the array.
*/
abstract NestedSet[] transitiveSets();
/**
* Returns true if the set is empty.
*/
public abstract boolean isEmpty();
/**
* Returns a collection of all unique elements of this set (including subsets)
* in an implementation-specified order as a {@code Collection}.
*
* <p>If you do not need a Collection and an Iterable is enough, use the
* nested set itself as an Iterable.
*/
public Collection<E> toCollection() {
return toList();
}
/**
* Returns a collection of all unique elements of this set (including subsets)
* in an implementation-specified order as a {code List}.
*
* <p>Use {@link #toCollection} when possible for better efficiency.
*/
public abstract List<E> toList();
/**
* Returns a collection of all unique elements of this set (including subsets)
* in an implementation-specified order as a {@code Set}.
*
* <p>Use {@link #toCollection} when possible for better efficiency.
*/
public abstract Set<E> toSet();
/**
* Returns true if this set is equal to {@code other} based on the top-level
* elements and object identity (==) of direct subsets. As such, this function
* can fail to equate {@code this} with another {@code NestedSet} that holds
* the same elements. It will never fail to detect that two {@code NestedSet}s
* are different, however.
*
* @param other the {@code NestedSet} to compare against.
*/
public abstract boolean shallowEquals(@Nullable NestedSet<? extends E> other);
/**
* Returns a hash code that produces a notion of identity that is consistent with
* {@link #shallowEquals}. In other words, if two {@code NestedSet}s are equal according
* to {@code #shallowEquals}, then they return the same {@code shallowHashCode}.
*
* <p>The main reason for having these separate functions instead of reusing
* the standard equals/hashCode is to minimize accidental use, since they are
* different from both standard Java objects and collection-like objects.
*/
public abstract int shallowHashCode();
@Override
public String toString() {
String members = Joiner.on(", ").join(directMembers());
String nestedSets = Joiner.on(", ").join(transitiveSets());
String separator = members.length() > 0 && nestedSets.length() > 0 ? ", " : "";
return "{" + members + separator + nestedSets + "}";
}
@Override
public Iterator<E> iterator() { return new NestedSetLazyIterator<>(this); }
}
|