Contract of Collection.contains violated in AbstractBaseGraph.edges
See original GitHub issueLet p
be an EndpointPair<Integer>
. The method AbstractBaseGraph#edges can return a Set<EndpointPair<Integer>> edges
for which edges.contains(p)
is true
, but e.equals(p)
is false
for each element e
. This violates the contract of java.util.Collection#contains:
Returns true if this collection contains the specified element. More formally, returns true if and only if this collection contains at least one element e such that Objects.equals(o, e).
Note the failing assertion in the following test:
@Test
public void contains_contract_violated() {
MutableGraph<Integer> undirectedGraph = GraphBuilder.undirected().build();
undirectedGraph.putEdge(1, 2);
Set<EndpointPair<Integer>> edges = undirectedGraph.edges();
EndpointPair<Integer> ordered = EndpointPair.ordered(1, 2);
Assertions.assertTrue(edges.contains(ordered));
Assertions.assertTrue(edges.stream().anyMatch(ordered::equals)); // fails
}
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:13 (11 by maintainers)
Top Results From Across the Web
Collections.sort() Comparison method violates its general ...
In your case you violate it when two Users have checkMatchConditions false , in which case compare(u1, u2) and compare(u2, u1) both return...
Read more >OUTSOURCING COLLECTIONS CONTRACTS What you ...
(d) A defendant is not liable for the collection fees authorized under Subsection (b) if the court of original jurisdiction has determined the ......
Read more >System.AddIn.Contract.Collections Namespace | Microsoft Docs
Contains interfaces that define collections of IContract and RemoteArgument objects.
Read more >How to Break a Contract With a Collections Agency
Breach of Contract. If the collections agency has breached a material term of the agreement, you will also be free to break your...
Read more >What Is a Breach of Contract in a Debt Collection Case
What is a breach of contract as it pertains to your business debt collection case? Get the details on what happens & what...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Thanks, @jbduncan.
As far as I can tell, neither of these cases exist in Google’s code base. However, that doesn’t tell us whether they exist in the rest of the world. 😃
I think we’ve settled on this change: that was the original subject of this issue, and I agree that we need to not violate the
Set.contains()
contract. Since we have an existing contract forhasEdgeConnecting()
that requires that it be consistent withedges().contains()
, that means that behavior needs to change as well.This is the remaining question, yes. 😃
@h908714124 thanks for the catch. This is a bug. It arose from a bug fix, but @cpovirk is correct that the behavior of
contains()
didn’t specifically come up in the review (@cpovirk, the API review which led to this change included “endpoint ordering mismatches” in the title if you want to look it up).@jbduncan thanks for the analysis; you are correct about the cause.
The original review was about fixing undefined behavior for mutations involving the case where someone added an unordered
EndpointPair
to a directed graph (the behavior is undefined, because the assignment of “nodeU” and “nodeV” to the endpoints is arbitrary).Unfortunately, I think that I got a bit too cute with the solution (and I don’t think any of the reviewers noticed the problem). Technically adding an ordered edge
<u, v>
to an undirected graph is…not invalid, because the graph can simply ignore the directionality of the endpoints. Our mistake was that we should not have (implicitly) concluded that you can say that the resultant graph contains a directed edge<u, v>
if there is an undirected edge connectingu
andv
.As @h908714124 pointed out, we should not have defined
contains()
in such a way as to be inconsistent withequals()
(that’s clearly a violation of theSet
contract as well as being weird) and it is also clear that an unorderedEndpointPair
should never be equal to an orderedEndpointPair
. Therefore we need to fix thecontains()
behavior.@cpovirk, since you’ve apparently already identified the failing tests (which implies that you have a CL with this change), I’d be happy to review a fix for this. Otherwise I’ll try to get to it.