Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.util.ArrayList#include? returns false incorrectly (9.1.3.0 onwards) #5569

Open
betesh opened this issue Jan 21, 2019 · 4 comments
Open

Comments

@betesh
Copy link

betesh commented Jan 21, 2019

$ rvm jruby 9.1.2.0  do ruby -e "j = java.util.ArrayList.new; j << java.lang.Integer.new(7); puts j.include?(7)"
true
$ rvm jruby 9.1.3.0  do ruby -e "j = java.util.ArrayList.new; j << java.lang.Integer.new(7); puts j.include?(7)"
false

I did a git bisect and traced this to commit 2e47a9d

Environment

  • JRuby version: All versions from 9.1.3.0 onwards

  • Operating system and platform:

$ uname -a
Linux 4.17.0-041700-generic #201806041953 SMP Mon Jun 4 19:55:25 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

Expected Behavior

When I insert a java.lang.Integer into a java.util.ArrayList and pass the corresponding Ruby Fixnum to #include?, I expect it to return true

Actual Behavior

Starting with jruby 9.1.3.0, it returns false

betesh referenced this issue Jan 21, 2019
... and use contains(Object) directly as the (Enumerable) base impl
loops over the collection making it highly non-effective (e.g. for sets)

9.0.5.0
```
                 user     system      total        real
ArrayList#include? hit  11.670000   1.150000  12.820000 ( 11.749035)
ArrayList#include? miss  9.840000   0.080000   9.920000 (  9.707464)
ArrayList#contains hit   0.730000   0.010000   0.740000 (  0.370432)
ArrayList#contains miss  0.350000   0.000000   0.350000 (  0.267981)
HashSet#include? hit    13.720000   0.020000  13.740000 ( 13.593915)
HashSet#include? miss    9.610000   0.020000   9.630000 (  9.543065)
HashSet#contains hit     0.410000   0.000000   0.410000 (  0.256134)
HashSet#contains miss    0.290000   0.000000   0.290000 (  0.213409)
LHashSet#include? hit   11.560000   0.020000  11.580000 ( 11.453787)
LHashSet#include? miss  11.840000   0.010000  11.850000 ( 11.752156)
LHashSet#contains hit    0.320000   0.000000   0.320000 (  0.227460)
LHashSet#contains miss   0.310000   0.000000   0.310000 (  0.220113)
```

before
```
                 user     system      total        real
ArrayList#include? hit   3.060000   0.000000   3.060000 (  3.057502)
ArrayList#include? miss  3.220000   0.010000   3.230000 (  3.232130)
ArrayList#contains hit   0.310000   0.000000   0.310000 (  0.308007)
ArrayList#contains miss  0.320000   0.000000   0.320000 (  0.313187)
HashSet#include? hit     3.040000   0.000000   3.040000 (  3.036603)
HashSet#include? miss    3.240000   0.010000   3.250000 (  3.237065)
HashSet#contains hit     0.160000   0.000000   0.160000 (  0.152719)
HashSet#contains miss    0.150000   0.000000   0.150000 (  0.154513)
LHashSet#include? hit    3.000000   0.000000   3.000000 (  2.987810)
LHashSet#include? miss   3.160000   0.000000   3.160000 (  3.165118)
LHashSet#contains hit    0.160000   0.000000   0.160000 (  0.160286)
LHashSet#contains miss   0.230000   0.000000   0.230000 (  0.156899)
```

after
```
                 user     system      total        real
ArrayList#include? hit   0.110000   0.000000   0.110000 (  0.098661)
ArrayList#include? miss  0.090000   0.000000   0.090000 (  0.087545)
ArrayList#contains hit   0.350000   0.000000   0.350000 (  0.352668)
ArrayList#contains miss  0.350000   0.000000   0.350000 (  0.351055)
HashSet#include? hit     0.070000   0.000000   0.070000 (  0.061353)
HashSet#include? miss    0.060000   0.000000   0.060000 (  0.058946)
HashSet#contains hit     0.180000   0.000000   0.180000 (  0.172549)
HashSet#contains miss    0.170000   0.000000   0.170000 (  0.171588)
LHashSet#include? hit    0.090000   0.000000   0.090000 (  0.071044)
LHashSet#include? miss   0.070000   0.000000   0.070000 (  0.060303)
LHashSet#contains hit    0.300000   0.000000   0.300000 (  0.208889)
LHashSet#contains miss   0.170000   0.000000   0.170000 (  0.166072)
```
@kares
Copy link
Member

kares commented Jan 22, 2019

interesting find, still I would consider the previous behaviour invalid and not inline with Ruby types.
collections are meant to behave in a similar fashion to Ruby types such as the good-old Array :

$ bin/jruby -e 'a = [ java.lang.Integer.new(1) ]; p a.include?(1); p a.include?(1.to_java); p a.include?(1.to_java(:int))'
false
false
true

previous functionality meant always going through a collection - so include? loops for Java sets etc.
... Enumerables convention is to not re-define include? as is for collection types (Array, Set)

also if you need the previous behaviour you could transplant Enumerable#include? for Collection

@kares kares added this to the Invalid or Duplicate milestone Jan 22, 2019
@betesh
Copy link
Author

betesh commented Jan 22, 2019

I would consider the previous behaviour invalid and not inline with Ruby types

I would expect include? to test whether any of the elements equal the arg. In the example in your comment, the (Ruby) Array does not include the arg because none of its elements are equal to the arg:

$ rvm jruby 9.1.3.0 do ruby -e "j = [ java.lang.Integer.new(7) ]; puts j.include?(7); puts j.first == 7; puts 7 == j.first; puts ([7] & j).inspect"
false
false
false
[]

However, in the case I reported, the equality operator returns true, making the behavior of include? very surprising:

$ rvm jruby 9.1.3.0 do ruby -e "j = java.util.ArrayList.new; j << java.lang.Integer.new(7); puts j.include?(7); puts j.first == 7; puts 7 == j.first; ; puts ([7] & j).inspect"
false
true
true
[7]

@googya
Copy link

googya commented Jan 29, 2019

[16] pry(main)> 7 == java.lang.Integer.new(7)
=> false

7 is not equal as java.lang.Integer.new(7), maybe that's the point

@betesh
Copy link
Author

betesh commented Jan 29, 2019

@googya JRuby supports automatic conversion between Java and Ruby types under certain circumstances but not all. However, equality and inclusion should be consistent for any given case, but in the case I reported, they are not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants