Closed prdoyle closed 2 years ago
Awesome! I'll test this out and merge it soon
This is great, thanks! The tests seem nice and thorough. I think at some point we should optimize it by having it check if list
is a Set
, and then if so preferring to iterate over whichever set is smaller (so we get O(mlgn)
with m<n) …but anyway that can be a future thing, I'll open an issue as a reminder.
@hrldcpr - I shied away from iterating over the shorter set because I wasn't sure I could preserve order correctly for the ordered set. The implementation I provided gives, I think, a logical ordering in all cases. (At least, it was the ordering that met the needs of my application. 😅)
I probably could have added special cases if a
or b
is empty or singleton.
For the implementation a.minusAll(a.minusAll(b))
, I think it always takes |a|+|b|-|a∩b| steps, which is ok but not awesome. Certainly some subclasses could do much better.
Another implementation could be based on looping through a
and calling minus
for each element that returns false for b.contains
. That would be O(a log b), which I think is never better unless |b| <= 2.
Good point about maintaining order. And yeah the different possible complexities are intriguing/subtle!
I like the current implementation, but I'll keep #103 open in case anyone stumbles upon it with a brilliant insight.
Fixes #96.
Unit tests
I've included some JUnit5
@ParameterizedTest
s. Apologies that the naming scheme for the test methods is so different. The existing JUnit4 scheme won't work because JUnit4 will think they're JUnit4 tests and they won't work. Since JUnit5 needs a different convention anyway, I've used the one I'm accustomed to, which takes the formconditions_expectedResult
.