001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.osm; 003 004import java.util.Objects; 005 006import org.openstreetmap.josm.tools.Pair; 007 008/** 009 * A directed pair of nodes (a,b != b,a). 010 * @since 12463 (extracted from CombineWayAction) 011 */ 012public class NodePair { 013 private final Node a; 014 private final Node b; 015 016 /** 017 * Constructs a new {@code NodePair}. 018 * @param a The first node 019 * @param b The second node 020 */ 021 public NodePair(Node a, Node b) { 022 this.a = a; 023 this.b = b; 024 } 025 026 /** 027 * Constructs a new {@code NodePair}. 028 * @param pair An existing {@code Pair} of nodes 029 */ 030 public NodePair(Pair<Node, Node> pair) { 031 this(pair.a, pair.b); 032 } 033 034 /** 035 * Replies the first node. 036 * @return The first node 037 */ 038 public Node getA() { 039 return a; 040 } 041 042 /** 043 * Replies the second node 044 * @return The second node 045 */ 046 public Node getB() { 047 return b; 048 } 049 050 /** 051 * Determines if this pair is successor of another one (other.b == this.a) 052 * @param other other pair 053 * @return {@code true} if other.b == this.a 054 */ 055 public boolean isSuccessorOf(NodePair other) { 056 return other.getB() == a; 057 } 058 059 /** 060 * Determines if this pair is predecessor of another one (this.b == other.a) 061 * @param other other pair 062 * @return {@code true} if this.b == other.a 063 */ 064 public boolean isPredecessorOf(NodePair other) { 065 return b == other.getA(); 066 } 067 068 /** 069 * Returns the inversed pair. 070 * @return swapped copy 071 */ 072 public NodePair swap() { 073 return new NodePair(b, a); 074 } 075 076 @Override 077 public String toString() { 078 return new StringBuilder() 079 .append('[') 080 .append(a.getId()) 081 .append(',') 082 .append(b.getId()) 083 .append(']') 084 .toString(); 085 } 086 087 /** 088 * Determines if this pair contains the given node. 089 * @param n The node to look for 090 * @return {@code true} if {@code n} is in the pair, {@code false} otherwise 091 */ 092 public boolean contains(Node n) { 093 return a == n || b == n; 094 } 095 096 @Override 097 public int hashCode() { 098 return Objects.hash(a, b); 099 } 100 101 @Override 102 public boolean equals(Object obj) { 103 if (this == obj) return true; 104 if (obj == null || getClass() != obj.getClass()) return false; 105 NodePair nodePair = (NodePair) obj; 106 return Objects.equals(a, nodePair.a) && 107 Objects.equals(b, nodePair.b); 108 } 109}