All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.common.graph.ElementOrder Maven / Gradle / Ivy

/*
 * Copyright (C) 2016 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.graph;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Objects;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.google.errorprone.annotations.Immutable;
import java.util.Comparator;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
 * Used to represent the order of elements in a data structure that supports different options for
 * iteration order guarantees.
 *
 * 

Example usage: * *

{@code
 * MutableGraph graph =
 *     GraphBuilder.directed().nodeOrder(ElementOrder.natural()).build();
 * }
* * @author Joshua O'Madadhain * @since 20.0 */ @Beta @Immutable public final class ElementOrder { private final Type type; @SuppressWarnings("Immutable") // Hopefully the comparator provided is immutable! private final @Nullable Comparator comparator; /** * The type of ordering that this object specifies. * *
    *
  • UNORDERED: no order is guaranteed. *
  • STABLE: ordering is guaranteed to follow a pattern that won't change between releases. * Some methods may have stronger guarantees. *
  • INSERTION: insertion ordering is guaranteed. *
  • SORTED: ordering according to a supplied comparator is guaranteed. *
*/ public enum Type { UNORDERED, STABLE, INSERTION, SORTED } private ElementOrder(Type type, @Nullable Comparator comparator) { this.type = checkNotNull(type); this.comparator = comparator; checkState((type == Type.SORTED) == (comparator != null)); } /** Returns an instance which specifies that no ordering is guaranteed. */ public static ElementOrder unordered() { return new ElementOrder(Type.UNORDERED, null); } /** * Returns an instance which specifies that ordering is guaranteed to be always be the same across * iterations, and across releases. Some methods may have stronger guarantees. * *

This instance is only useful in combination with {@code incidentEdgeOrder}, e.g. {@code * graphBuilder.incidentEdgeOrder(ElementOrder.stable())}. * *

In combination with {@code incidentEdgeOrder}

* *

{@code incidentEdgeOrder(ElementOrder.stable())} guarantees the ordering of the returned * collections of the following methods: * *

    *
  • For {@link Graph} and {@link ValueGraph}: *
      *
    • {@code edges()}: Stable order *
    • {@code adjacentNodes(node)}: Connecting edge insertion order *
    • {@code predecessors(node)}: Connecting edge insertion order *
    • {@code successors(node)}: Connecting edge insertion order *
    • {@code incidentEdges(node)}: Edge insertion order *
    *
  • For {@link Network}: *
      *
    • {@code adjacentNodes(node)}: Stable order *
    • {@code predecessors(node)}: Connecting edge insertion order *
    • {@code successors(node)}: Connecting edge insertion order *
    • {@code incidentEdges(node)}: Stable order *
    • {@code inEdges(node)}: Edge insertion order *
    • {@code outEdges(node)}: Edge insertion order *
    • {@code adjacentEdges(edge)}: Stable order *
    • {@code edgesConnecting(nodeU, nodeV)}: Edge insertion order *
    *
* * @since 29.0 */ public static ElementOrder stable() { return new ElementOrder(Type.STABLE, null); } /** Returns an instance which specifies that insertion ordering is guaranteed. */ public static ElementOrder insertion() { return new ElementOrder(Type.INSERTION, null); } /** * Returns an instance which specifies that the natural ordering of the elements is guaranteed. */ public static > ElementOrder natural() { return new ElementOrder(Type.SORTED, Ordering.natural()); } /** * Returns an instance which specifies that the ordering of the elements is guaranteed to be * determined by {@code comparator}. */ public static ElementOrder sorted(Comparator comparator) { return new ElementOrder(Type.SORTED, checkNotNull(comparator)); } /** Returns the type of ordering used. */ public Type type() { return type; } /** * Returns the {@link Comparator} used. * * @throws UnsupportedOperationException if comparator is not defined */ public Comparator comparator() { if (comparator != null) { return comparator; } throw new UnsupportedOperationException("This ordering does not define a comparator."); } @Override public boolean equals(@Nullable Object obj) { if (obj == this) { return true; } if (!(obj instanceof ElementOrder)) { return false; } ElementOrder other = (ElementOrder) obj; return (type == other.type) && Objects.equal(comparator, other.comparator); } @Override public int hashCode() { return Objects.hashCode(type, comparator); } @Override public String toString() { ToStringHelper helper = MoreObjects.toStringHelper(this).add("type", type); if (comparator != null) { helper.add("comparator", comparator); } return helper.toString(); } /** Returns an empty mutable map whose keys will respect this {@link ElementOrder}. */ Map createMap(int expectedSize) { switch (type) { case UNORDERED: return Maps.newHashMapWithExpectedSize(expectedSize); case INSERTION: case STABLE: return Maps.newLinkedHashMapWithExpectedSize(expectedSize); case SORTED: return Maps.newTreeMap(comparator()); default: throw new AssertionError(); } } @SuppressWarnings("unchecked") ElementOrder cast() { return (ElementOrder) this; } }