0

I am trying to do subtract operation on ArrayList using removeAll. But the outcome is not as expected. Actually its not removing anything.

ArrayList<Integer> tempSelectedPrivilges = new ArrayList<Integer>(privPickList.getTarget());
log.debug("Original selected : " + selectedPrivilges);        
log.debug("temp selected : " + tempSelectedPrivilges);
ArrayList<Integer> addedPrivileges = new ArrayList<>(tempSelectedPrivilges);
ArrayList<Integer> deletedPrivileges = new ArrayList<>(selectedPrivilges);        
log.debug("Add : " + addedPrivileges);
log.debug("Delete : " + deletedPrivileges);
addedPrivileges.removeAll(selectedPrivilges);
deletedPrivileges.removeAll(tempSelectedPrivilges);
log.debug("Add : " + addedPrivileges);
log.debug("Delete : " + deletedPrivileges);

Output is something like this :

Original selected : [2, 3]
temp selected : [2, 1, 4, 5, 6]
Add : [2, 1, 4, 5, 6]
Delete : [2, 3]
Add : [2, 1, 4, 5, 6]
Delete : [2, 3]

Only problem I see is :

 privPickList.getTarget() returns a List<Integer> rather than ArrayList<Integer>.

Because when I create tempSelectedPrivileges like this, it works prefectly fine :

ArrayList<Integer> tempSelectedPrivilges = new ArrayList<>();
tempSelectedPrivilges.add(3);
tempSelectedPrivilges.add(5);
tempSelectedPrivilges.add(6);

Why creating ArayList of Integer from List of integer is creating problems?

And when I am trying to do :

for(Integer i : privPickList.getTarget()) {
    tempSelectedPrivilges.add(i);
}

there is no compile time error. But runtime error

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer

on line

tempSelectedPrivilges.add(i);
Akhil
  • 533
  • 2
  • 11
  • 26
  • Have you overridden equals() method in the class?? – Navish Sharma Nov 21 '14 at 07:44
  • Show us how `getTarget` fills the List or preferably a [minimal, verifiable example](http://stackoverflow.com/help/mcve). – Radiodef Nov 21 '14 at 09:31
  • Your variables should be of type `List`: See [Liskov substitution principle](http://en.wikipedia.org/wiki/Liskov_substitution_principle) – Bohemian Nov 21 '14 at 09:57
  • privPickList is of type [org.primefaces.model.DualListModel](http://www.primefaces.org/docs/api/3.5/org/primefaces/model/DualListModel.html) and signature of getSource is `public List getSource()` – Akhil Nov 21 '14 at 11:00
  • I updated the question at the end. – Akhil Nov 21 '14 at 11:47
  • @Akhil The elements returned by `getTarget()` method are not of type Integer. When you are using ArrayList constructor to create new list, the new list is created without type checking. But when you are adding one element at a time, the elements are typecasted first and then added(typecasting statements are added at compile time). That's why it is throwing ClassCastException. – Sanjeev Kumar Nov 21 '14 at 11:52
  • You are evidently using a [raw type](http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it) somewhere. – Radiodef Nov 21 '14 at 11:57
  • @SanjeevSharma but its showing return type as `List`. and when I am trying to use `String s : list.getTarget()`, it is showing compile time error as return type is `List` for getTarget. – Akhil Nov 21 '14 at 12:07
  • In java generics, the type information is not available at runtime. It means that if a function retuns `List` it will be converted to `List` by compiler. The compiler has no way of deciding at compile time what type of elements a list may contain. So generics only provide syntactic sugar for strong type checking, you can still make errors with raw types. – Sanjeev Kumar Nov 21 '14 at 12:21
  • So whats the solution here? – Akhil Nov 21 '14 at 12:28
  • You should look at the implementation of `getTarget()` method to find why is it returning string elements despite integer in its signature. If it is implemented by you then you should correct the implementation. If it is third party library then you can try to convert(Integer.parseInt) the string elements of the list to integer while adding to your list. – Sanjeev Kumar Nov 21 '14 at 12:55
  • made a workaround like this : 'for(Object i : privPickList.getTarget()) { tempSelectedPrivilges.add(Integer.parseInt(i.toString())); }' – Akhil Nov 21 '14 at 15:02

1 Answers1

0

Works fine for me (using List<Integer>) like this in Java 8,

public static void main(String[] args) throws Exception {
    List<Integer> selectedPrivilges = new ArrayList<>(Arrays.asList(2, 3));
    List<Integer> tempSelectedPrivilges = new ArrayList<>(Arrays.asList(2,
            1, 4, 5, 6));
    System.out.println("Original selected : " + selectedPrivilges);
    System.out.println("temp selected : " + tempSelectedPrivilges);
    List<Integer> addedPrivileges = new ArrayList<>(tempSelectedPrivilges);
    List<Integer> deletedPrivileges = new ArrayList<>(selectedPrivilges);
    System.out.println("Add : " + addedPrivileges);
    System.out.println("Delete : " + deletedPrivileges);
    addedPrivileges.removeAll(selectedPrivilges);
    deletedPrivileges.removeAll(tempSelectedPrivilges);
    System.out.println("Add : " + addedPrivileges);
    System.out.println("Delete : " + deletedPrivileges);
}

Output is (as you seem to have expected)

Original selected : [2, 3]
temp selected : [2, 1, 4, 5, 6]
Add : [2, 1, 4, 5, 6]
Delete : [2, 3]
Add : [1, 4, 5, 6]
Delete : [3]
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249