Distinguishing between ArrayList#remove() methods - java

I have an ArrayList of integers, as such;
ArrayList<Integer> list = new ArrayList<>();
list.add(8);
list.add(20);
list.add(50);
I also have a variable, that is set to a random item from that ArrayList. I want to remove the item in the variable from the arraylist, so I tried this;
list.remove(var);
However, it assumes that because var is an integer, it tries to get the index at the location of var instead of searching for and removing it. But because every item in the list is larger than the size of it, it always gives an ArrayOutOfBoundsException. Is there a way to force Java to attempt to use the proper remove method?

You need to pass an Integer - your main options are:
Integer valueToRemove = 8;
list.remove(valueToRemove);
int anotherOne = 20;
list.remove(Integer.valueOf(anotherOne));
int andFinally = 50;
list.remove((Integer) andFinally);

When you call add(8), it is actually autoboxed so the actual call is add(new Integer(8)). That doesn't happen on the remove() call because there's actually a remove() call that takes an int as an argument. The solution is to create the Integer object yourself instead of relying on autoboxing: list.remove(new Integer(var)).

Related

How do I add arrays to an Arraylist of Arrays (Arraylist<Integer[]>)

I want to save the steps pf my player-character in a Sokoban-game.
So at first i want to fill an Array of int x and y, called "pos" with the actual position of the character.
And than i want to add this array to an ArrayList of Arrays, called "moves".
Array for one player-position:
int[] pos = new int [2];
ArrayList for all steps, the player made in the level:
Arraylist<Integer[]> moves = new ArrayList<>();
"int[]" makes an error, if placed inside the pointy brackets at the ArrayList.
How do i add the Array pos to the ArrayList moves?
This works completely fine with int[]. However int[] != Integer[], Use same in both places.
int[] pos = new int[2];
ArrayList<int[]> arrayList = new ArrayList<>();
pos[0] = 1;
pos[1] = 2;
arrayList.add(pos);
System.out.println(arrayList.get(0)[0]+ " "+ arrayList.get(0)[1]);
int and Integer are two different things (I struggled with this as well when I first learned Java a long time ago.
int is a so-called primitive datatype, which means it is not an object. Integer is a wrapper class, basically a class whose only purpose is to contain an
int so that it can be handled as an object. Since Java 5, there is "autoboxing", which means you can assign int values to Integer variables and vice versa, and the compiler will handle it silently. This tends to muddle the difference, but it still is there and important - such as in this case.
So if you want to store instances of int[] in an ArrayList, you need an ArrayList<int[]>, not an ArrayList<Integer[]>.
However, it is impossible to have an ArrayList<int> because ArrayList can only store Objects (the generic types exist only for the compiler), not primitives.
Oh yes, and to add an element to the list, use
Arraylist<int[]> moves = new ArrayList<>();
arrayList.add(pos);
You could have found this in the API doc for ArrayList - you should really learn to use the API doc, you will need it all the time to answer questions such as this.
You can also make class (for example Pos) and make x and y as attributes and make constructor. The you can make the type of arraylist is Pos
ArrayList arrayList = new ArrayList<>();
arrayList.add(new Pos(3,2));

Checking if an ArrayList contains more than 1 of the same integer and removing them from the list?

I ran into a seemingly simple problem that I haven't been able to figure out. Basically, my list holds a number of ints which represent different items, which works fine, but I need to be able to check if the list contains the same integer more than once and then remove them from the list.
if (myList.contains(100)) { // I want to check if the int '100' exists in myList twice
myList.remove(new Integer(100)); // I want to remove the 2 aforementioned duplicate integers
}
Apologies if my explanation wasn't the clearest. Thanks in advance!
EDIT: To clarify, I want the list to contain duplicates but I want to be able to check if the duplicate exists X times and then remove those instances from the list.
i.e.
I might want to add the int 100 7 times, and then later check if it exists twice and then remove 2 instances of it from the list only.
you can create a method to accomplish the task at hand, something along the lines of this:
private static boolean removeSpecfiedNumber(int number,int numberOfTimes, List<Integer> integerList){
if(integerList.stream().filter(x -> x == number).count() >= numberOfTimes){
for (int i = 0; i < numberOfTimes; i++) {
integerList.remove((Integer)number);
}
return true;
}
return false;
}
The parameter number is the number you want to check its occurrences i.e. 100 in your case.
The parameter numberOfTimes is the number of times you want to remove that element from the list.
The parameter integerList is, of course, the list you want to remove the elements from.
Let's take the code below as an example:
List<Integer> myList = new ArrayList<>();
myList.add(100);
myList.add(200);
myList.add(100);
myList.add(100);
myList.add(100);
myList.add(100);
myList.add(100);
myList.add(100);
removeSpecfiedNumber(100,2,myList);
System.out.println(myList);
this will remove 100 twice from myList and should, therefore, yield the elements below:
[200, 100, 100, 100, 100, 100]
The method return type can be void if you want, However, the return type of boolean can come in handy at times hence I've used that approach.
Also, you need not use the static modifier if you're dealing with objects, therefore you can remove it.
1) myList.remove(new Integer(100)); will remove only the first occurrence that is equals to 100.
You should loop on remove() while the list contains still an object with the same value.
2) To know if the list contains more than once the object, you could use indexOf() and lastIndexOf() .
If these are distinct, it means that you have more than one element.
So according to your requirement, you can remove all of them with the method described in the point 1.
Integer valueToCheck = 100;
if ( myList.indexOf(valueToCheck) != myList.lastIndexOf(valueToCheck) ) {
while (myList.contains(valueToCheck)){
myList.remove(valueToCheck);
}
}
You can use a Set which does not allowed duplicate keys e.g.
Set<Ineger> foo = new HashSet<>(myList);
And you can create a new List from that or use it as it is.
Starting java 8 you can use java stream api in such way:
List<Integer> i = new ArrayList<Integer>();
i.add(1);
i.add(2);
i.add(3);
i.add(1);
List<Integer> collect = i.stream().distinct().collect(Collectors.toList());
NOTE: new list will be created.

Searching for index of array from arraylist

I want to find a index of an array in array list such that,
String[]names=new String[x];
new ArrayList<String>(Arrays.asList(names));
int w=......indexOf(search);
I don't know what am I going to suppose to write on ......
The List interface has the indexOf method:
Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element
So, you just need to invoke this method.
Note that
new ArrayList<String>(Arrays.asList(names));
creates a List (two Lists, actually), but doesn't actually store the created list anywhere; so you don't end up with anything you can invoke the method on.
Either:
List<String> list = new ArrayList<String>(Arrays.asList(names));
int w = list.indexOf(search);
or:
int w = new ArrayList<String>(Arrays.asList(names)).indexOf(search);
or, even easier, since Arrays.asList returns a List, and you don't need to mutate the list to search it:
int w = Arrays.asList(names).indexOf(search);

Variable length objects and using traditional for loop

In one of my methods, I need to pass objects as variable length parameters.
However, first I need to process the last object and then based on that many other processing will be done. I could not figure out how to use the index for each of the items in the variable argument list using traditional for loop and then index. So I used below code. Is this the right method to copy the object reference to another Array or ArrayList as I did? Otherwise what is the best method to access the specific object first and then loop through all other objects.
public static int generateConnectedPatterns(String endStr,Moorchana.MoorchanInnerClass...totalPatterns) {
// First copy all the objects to new ArrayList or Array of objects
ArrayList <Moorchana.MoorchanInnerClass> objectList = new ArrayList<>();
objectList.addAll(Arrays.asList(totalPatterns));
//Temporarily use lastObject variable for convenience.
Moorchana.MoorchanInnerClass lastObject = objectList.get(objectList.size()-1);
// Split the last input string into swaras
ArrayList<Integer> indices = new ArrayList<>();
ArrayList<String> tempPatternList = new ArrayList<>();
splitInputPatternIntoArrayList(tempPatternList , indices, lastObject.rawInputString);
if (Moorchana.validatePresenceInSwaraPool(endStr, lastObject.returnOuterObjectRef().swaraPool) == -1) {
return (-1);
}
// Get the index of the ending String
int indexofEndStr = lastObject.returnOuterObjectRef().getSwaraIndex(endStr);
// Now get the number of patterns to be generated.
int count = lastObject.returnOuterObjectRef().getPatternCount(indices, indexofEndStr);
// Now Do remaining programming here based on the count.
return(Constants.SUCCESS);
}
A varargs is basically an array.
Once you checked for null and length, you can access the last element just as you would with an array.
On the other hand, Arrays.asList returns a fixed-size list, which means you will not be able to manipulate its size later on, so beware of UnsupportedOperationExceptions.
In short, you can use the varargs as array and reference the last element once the necessary checks are performed.
Treat totalPatterns as an array.
To identify the last element: totalPatterns[totalPatterns.length-1]
for iteration, you could use an enhanced for loop.
for ( Moorchana.MoorchanInnerClass d : totalPatterns){...}
Note: Do a null check before you process the array, if you are not sure of the input being passed.

ArrayList with returned index on add value

I am looking for a java data structure similar to an ArrayList that when I do an add or a push with only a value argument an index will be returned for me automatically.
For example:
ArrayList<String> elements = new ArrayList<String>();
String element = "foo";
String elementTwo = "bar";
int index1 = elements.add(element); //note this does not exist, i.e. returns bool in api
int index2 = elements.add(elementTwo);
System.out.println(elements.get(index1)); //would give "foo"
I could see writing a wrapper class around ArrayList that manages a counter that is incremented on every add operation and invoking:
ArrayList.add(int index, E element)
Do you really need to write a wrapper around ArrayList for this? This seems like something simple enough to be provided out of the box somewhere?
Edit:
I need the index (key) to be fixed and unique for this usecase. A map was suggested and I agree with that. Does anyone know of a map implementation that gives you an automatically (uniquely) generated key on a value insert? I am just trying to decide if I need to implement my own wrapper for this.
The element will be added at the end of the list. So you can use elements.size()-1 to get the new elements index.
Note that this will not work reliable if multiple threads are modifying the list at the same time.
EDIT: Also note that it might not be a good idea to use an ArrayLists index as a unique ID because an elements index can change (for example when you remove an element or insert a new one using add(int, Object)). If this is a problem depends on what you want to do with the index: If you only need it for a short time after adding an element and can be sure that the list is not modified in the meantime, there is no problem. In the other case even a method returning the index when calling add(Object) would not help because the index does not get updated in anyway. To prevent this issue you can:
Make sure you never remove elements from the list and never add elements using add(int, Object).
Instead of removing elements you could also set them to null using the method set(int, null). This way no elements index will change.
Use some other data structure like for example a map with a custom ID like helloannalil suggests in his answer.
EDIT 2: I did not find a appropriate, ready to use implementation (but this does not mean there is none, of course). To suggest a good solution, more information on the intended use of the data structure is needed, but here are some ideas and notes:
If the maximum number of elements is not to large, an ArrayList could be used and the elements index represents the ID. As stated above, to remove an element it can be set to null so that no indices are changed. When inserting, positions with null values can be reused.
You can also use one of the two methods show in this answer: https://stackoverflow.com/a/8939049/1347968 (keywords AtomicLong or IdentityHashMap)
Do not depend on the "uniqueness" of Object.hashCode() or System.identityHashCode(Object) as it is not guaranteed (try it by running the example at the bottom of Suns/Oracles Bug #6321873).
Well what I do in that cases (I love ArrayLists) is to get the last index by asking the size of the list:
String thing = "theThing";
List<String> strList = new ArrayList<String>();
strList.add(thing);
int indexOfThing = strList.size() - 1;
I mean, is easier than implement your own List and just works.
if you really want this function, you can use map but not list
Based on your comments and edited question I think you can extend a HashMap for your use like this:
public class MyMap<V> extends HashMap<Integer, V> {
private static final long serialVersionUID = 1L;
public int add(V elem) {
int key = System.identityHashCode(elem);
super.put(key, elem);
return key;
}
}
Then inside your class declare MyMap like this:
private MyMap<String> map = new MyMap<String>();
And then add your elements to MyMap like this:
.....
.....
String element = "foo";
String elementTwo = "bar";
int index1 = map.add(element);
int index2 = map.add(elementTwo);
Now you have index1 and index2 as indices of you inserted strings that you can use or pass around for the lifetime of your application. You can insert or remove elements in MyMap as many times you want but your indices (index1 and index2) will give you back your inserted elements like this:
String elem1 = map.get(index1); // will return "foo"
String elem2 = map.get(index2); // will return "bar"
String thing = "theThing";
List<String> strList = new ArrayList<String>();
strList.add(thing);
int indexOfThing = strList.size() - 1;
If you remove an item, this will no longer work.

Categories