can not use in operator when passing java ArrayList<Integer> to python, but ArrayList<String> works well
Closed this issue · 5 comments
Describe the bug
I passed ArrayList and ArrayList to python env. The python code is as follows,
`if "1" in stringListA:
#do something
if 1 in integerListB:
#do something else`
stringListA = ["1"];integerListB = [1];in java and use
Object result = interp.invoke("mainFunc", new Object[] { inputCodeParams });
sending these two lists in a map named inputCodeParams to python env.
The program entered the first branch, but it didn't enter the second one. I tested that the integerListB did have the __contains__
method, but the in operator doesn't work correctly. Is there any different support between these two types? Or should I modify my usage?
To Reproduce
write the code above
Expected behavior
enter the second branch
Environment (please complete the following information):
- OS Platform, Distribution, and Version: linux
- Python Distribution and Version: python 3.11
- Java Distribution and Version: 11
- Jep Version: the newest version
btw when I used list(integerListB) casting the type to python list, the 'in' operator works correctly.
The __contains__
implementation for Java collections converts the Python object into a Java object and calls contains() on the Java collection. A Python int is converted to a Long in Java so the Long is not found in the list of Integers. It would work better if you use an ArrayList or if you convert the Python int to an Integer before checking if it is in the List. Here is some code in the jep interpreter that shows some examples of interacting with different type of ArrayList in python
>>> from java.util import ArrayList
>>> from java.lang import Integer, Long
>>> stringList = ArrayList(["1"])
>>> intList = ArrayList([Integer(1)])
>>> longList = ArrayList([Long(1)])
>>> "1" in stringList
True
>>> 1 in intList
False
>>> 1 in longList
True
>>> Integer(1) in intList
True
>>> Integer(1) in longList
False
>>> Long(1) in intList
False
>>> Long(1) in longList
True
The
__contains__
implementation for Java collections converts the Python object into a Java object and calls contains() on the Java collection. A Python int is converted to a Long in Java so the Long is not found in the list of Integers. It would work better if you use an ArrayList or if you convert the Python int to an Integer before checking if it is in the List. Here is some code in the jep interpreter that shows some examples of interacting with different type of ArrayList in python>>> from java.util import ArrayList >>> from java.lang import Integer, Long >>> stringList = ArrayList(["1"]) >>> intList = ArrayList([Integer(1)]) >>> longList = ArrayList([Long(1)]) >>> "1" in stringList True >>> 1 in intList False >>> 1 in longList True >>> Integer(1) in intList True >>> Integer(1) in longList False >>> Long(1) in intList False >>> Long(1) in longList True
@bsteffensmeier Thanks very much. Is there any other method to solve this problem if I want to retain python programming habits. I don't understand that why does "in" operation convert python object to java object. why not just use it in python env?
Is there any other method to solve this problem if I want to retain python programming habits.
- You can extend ArrayList and override contains to convert Long to Integer.
- You can use an int[] instead of ArrayList
- You can extend ArrayList and implement
__contains__
to take an Integer - You can convert your ArrayList to a Python list
- You can use an ArrayList instead of ArrayList
I don't understand that why does "in" operation convert python object to java object. why not just use it in python env?
Since ArrayList is a Java List it only contains Java objects so the only way to test if a Python object is in the List is to convert it to a Java object. It works how you expect when you use list(integerListB)
because you no longer have a Java List.