eclipse-collections
eclipse-collections copied to clipboard
Override Java 8 default method Collection#removeIf
As mentioned in https://github.com/eclipse/eclipse-collections/issues/500, the Collection#removeIf
has not been overridden in Eclipse Collection yet.
I would like to work on that!
Thanks for volunteering @aqsa505. I assigned the issue to you.
Can I try to solve the issue if it is open.
Hi, there seems no progress on this. Can I work on this @donraab ?
The challenge with this issue is what exactly to do. I'm going to share some thoughts here @aqsa505 to hopefully make this easier to approach.
The MutableCollection
class in Eclipse Collections defines removeIf
as follows:
boolean removeIf(org.eclipse.collections.api.block.predicate.Predicate<? super T> predicate);
There is an additional removeIfWith
method on MutableCollection
. This method can remain as is.
<P> boolean removeIfWith(org.eclipse.collections.api.block.predicate.Predicate2<? super T, ? super P> predicate, P parameter);
The Collection
class in JDK defines removeIf
as follows:
default boolean removeIf(java.util.function.Predicate<? super E> filter)
I believe Eclipse Collections has had removeIf
since before it was open sourced in 2012. I was able to see we changed the return type of removeIf
to return boolean in 2015 to be consistent with JDK method which was added in Java 8 in 2014.
Proposal:
I think we should just remove the EC overload of removeIf
in MutableCollection
and change the implementations to match the JDK signature with java.util.function.Predicate
. The EC Predicate
interface extends the JDK Predicate
interface, so this should be a source compatible change. This is most likely not a binary compatible change, but I think that will be ok if this makes it in time for 12.0 release.
I would like to hear thoughts from the other committers @motlin @nikhilnanivadekar @prathasirisha @mohrezaei on this proposal.
hmmm... Not a fan of the proposal. There are at least two other options:
- Just override the JDK method. This is the maximal compatibility option.
- Deprecate ec.Predicate. Leave the interface for backward compatibility, but search/replace with jdk.Predicate everywhere. This is the maximal cleanup option.
Thanks Moh. I think option 1 is fine, and should be easy enough to implement. I think option 2 would be hard to do. The reason I was suggesting removing overload on MutableCollections
is that it might be confusing to developers having two removeIf
methods defined, but then again this has been the case already for the past 8 years since Java 8 was released.
I tried the code below and was surprised there wasn't an ambiguity problem with using a lambda. I'm guessing it might be because EC Predicate extends JDK Predicate, and the more specific removeIf
on MutableCollection
is chosen.
@Test
public void removeIf()
{
MutableList<Integer> list = Lists.mutable.with(1, 2, 3);
list.removeIf(each -> each % 2 == 0);
Assertions.assertEquals(Lists.mutable.with(1, 3), list);
}
I was surprised the lambda didn't require a cast, although casting does work and calls the implementation on Collection
.
@Test
public void removeIf()
{
MutableList<Integer> list = Lists.mutable.with(1, 2, 3);
list.removeIf((java.util.function.Predicate<Integer>) (each -> each % 2 == 0));
Assertions.assertEquals(Lists.mutable.with(1, 3), list);
}
This blog: @.***/eclipse-collections-10-4-0-released-7c5b3f43c0f0
And more specifically this blog: https://stuartmarks.wordpress.com/2020/09/22/incompatibilities-with-jdk-15-charsequence-isempty/
covers the reasons that can cause ambiguity thus clarifying why this is not ambiguous.
On Mon, Apr 17, 2023 at 7:22 AM Donald Raab @.***> wrote:
Thanks Moh. I think option 1 is fine, and should be easy enough to implement. I think option 2 would be hard to do. The reason I was suggesting removing ours is that it might be confusing to developers having two removeIfs defined, but then again this has been the case already for the past 8 years since Java 8 was released.
I tried the code below and was surprised there wasn't an ambiguity problem with using a lambda. I'm guessing it might be because EC Predicate extends JDK Predicate, and the more specific removeIf on MutableCollection is chosen.
@Test public void removeIf() { MutableList<Integer> list = Lists.mutable.with(1, 2, 3); list.removeIf(each -> each % 2 == 0); Assertions.assertEquals(Lists.mutable.with(1, 3), list); }
I was surprised the lambda didn't require a cast, although casting does work and calls the implementation on Collection.
@Test public void removeIf() { MutableList<Integer> list = Lists.mutable.with(1, 2, 3); list.removeIf((java.util.function.Predicate<Integer>) (each -> each % 2 == 0)); Assertions.assertEquals(Lists.mutable.with(1, 3), list); }
— Reply to this email directly, view it on GitHub https://github.com/eclipse/eclipse-collections/issues/1432#issuecomment-1510578466, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACLY4XITAC46DAO6Y2FVRCDXBSO7DANCNFSM6AAAAAAUS56E3Y . You are receiving this because you were mentioned.Message ID: @.***>
I tried option 2. Documenting here for posterity.
- Use IDE->rename ec.Predicate.accept to someUniqueString334455
- replace in files,
import ec.Predicate
withimport jdk.Predicate
- replace in files,
someUniqueString334455
withtest
. Rollback changes to ec.Predicate. - search
accept
in stg files. for files that are changed because of the above, replace usages ofaccept
withtest
for Predicate (but not Predicate2, etc). - maven->test. One test required an extra import of jdk.Predicate to compile.
- The biggest issue happens around serialization of block.function classes that have a Predicate member. jdk.Predicate is not serializable. One possibility would be to leave these classes alone. Gave up at this point.
Ok, @aqsa505 I think you can go ahead with option 1 from @mohrezaei . Just override the JDK method in MutableCollection
. It should be doable via a default method that delegates to our current removeIf
method using a method reference.
Hi @donraab I would like to take this up, if nobody is working on it now
Thanks for volunteering @aditya-32. It is assigned currently to @aqsa505. I'll wait for her to comment whether she is working on it currently.