How do you find the index of the value(a String Value) from an arrayList? [duplicate] - java

For an Android app, I have the following functionality
private ArrayList<String> _categories; // eg ["horses","camels"[,etc]]
private int getCategoryPos(String category) {
for(int i = 0; i < this._categories.size(); ++i) {
if(this._categories.get(i) == category) return i;
}
return -1;
}
Is that the "best" way to write a function for getting an element's position? Or is there a fancy shmancy native function in java the I should leverage?

ArrayList has a indexOf() method. Check the API for more, but here's how it works:
private ArrayList<String> _categories; // Initialize all this stuff
private int getCategoryPos(String category) {
return _categories.indexOf(category);
}
indexOf() will return exactly what your method returns, fast.

ArrayList<String> alphabetList = new ArrayList<String>();
alphabetList.add("A"); // 0 index
alphabetList.add("B"); // 1 index
alphabetList.add("C"); // 2 index
alphabetList.add("D"); // 3 index
alphabetList.add("E"); // 4 index
alphabetList.add("F"); // 5 index
alphabetList.add("G"); // 6 index
alphabetList.add("H"); // 7 index
alphabetList.add("I"); // 8 index
int position = -1;
position = alphabetList.indexOf("H");
if (position == -1) {
Log.e(TAG, "Object not found in List");
} else {
Log.i(TAG, "" + position);
}
Output: List Index : 7
If you pass H it will return 7, if you pass J it will return -1 as we defined default value to -1.
Done

If your List is sorted and has good random access (as ArrayList does), you should look into Collections.binarySearch. Otherwise, you should use List.indexOf, as others have pointed out.
But your algorithm is sound, fwiw (other than the == others have pointed out).

Java API specifies two methods you could use: indexOf(Object obj) and lastIndexOf(Object obj). The first one returns the index of the element if found, -1 otherwise. The second one returns the last index, that would be like searching the list backwards.

There is indeed a fancy shmancy native function in java you should leverage.
ArrayList has an instance method called
indexOf(Object o)
(http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html)
You would be able to call it on _categories as follows:
_categories.indexOf("camels")
I have no experience with programming for Android - but this would work for a standard Java application.
Good luck.

the best solution here
class Category(var Id: Int,var Name: String)
arrayList is Category list
val selectedPositon=arrayList.map { x->x.Id }.indexOf(Category_Id)
spinner_update_categories.setSelection(selectedPositon)

Use indexOf() method to find first occurrence of the element in the collection.

The best way to find the position of item in the list is by using Collections interface,
Eg,
List<Integer> sampleList = Arrays.asList(10,45,56,35,6,7);
Collections.binarySearch(sampleList, 56);
Output : 2

Related

Passing method of one class into another [duplicate]

This question already has answers here:
Passing a method from another class
(4 answers)
Closed 5 years ago.
My problem is that I need to getSymbol from Element class.
I would normally establish an object in PeriodicTable like this:
Element e = new Element();
then use e.getSymbol within method in order to use it for comparison.
So, in order to complete first task and print entire list of elements, I declared an array within PeriodicTable like this:
Element[] objects = new Element[ARRAY_SIZE];
I'm guessing I declared it correctly, as it does run entire list of elements.
Again, I am having problems getting getSymbol into my method in PeriodicTable.
Any helpful suggestions, please?
For this method, a user will input a symbol for an element. The method will search for the element and return its index (in the array). Then, it will use the index to display that single element and all of its other information, using the toString method from the Element class.
public int searchBySymbol(String sym)
{
int index = 0;
boolean found = false;
for (int i = 0; i < objects.length; i++)
{
objects[i] = objects.getSymbol;
}
while (index < objects.length && !found)
{
if (objects[index].equals(sym))
{
found = true;
}
else
{
index++;
}
}
if(found)
{
System.out.println("Found at position: " + index);
System.out.println(objects[index].toString());
}
else
{
System.out.println("Not found");
}
}
You definitely don't need two loops in there first of all, there are two solutions to this:
(Recommended) If searching Elements by symbol will be the your main way of looking up Elements, consider using a HashMap to contain the data rather than an Element array as HashMaps allow look up of objects by a key e.g. HashMap<String, Element>. Lookup the HashMap API or check this example: http://beginnersbook.com/2013/12/hashmap-in-java-with-example/
(Quick fix) Rather than using two loops to get the field and compare, in Java it is good practice to define accessor methods such as getSymbol() and return the field rather than directly accessing it. Using this method you can simplify your code into...
for (Element e : objects) {
if (e.getSymbol().equals(sym) {
return true;
}
}
//return false after the loop omits the need for an explicit boolean variable`
Edit: Usual for loop construct for index access. The index number is essentially tracked by the iterator variable int i so you do not need a separate variable to track it.
for (int i = 0; i < objects.length; i++) {
if (objects[i].getSymbol().equals(sym)) {
//print i to show index number
//print objects[i].toString();
return true;
}
}
//print not found...
return false;

Implementing an equals() method to compare contents of two 'bag' objects

I am working on a school assignment. The objective is to practice GUI's, clone() methods, and using/ modifying existing code. I am trying to write an equals method in the way the instructor desires-- by using a clone of the object, removing items from the bag (returns boolean based on success or failure to remove).
The bag is represented in an array, and should return true in cases such as {1,2,3} and {3,2,1}, ie order does not matter, only the number of each number present in the arrays.
Here is the issue
It works in most cases, however there is a bug in cases where the bags contain numbers as such: {1,1,2} and {1,2,2} and other similar iterations. It is returning true instead of false.
I believe it has something to do with the remove() method we are supposed to use. If i understand it correctly, it is supposed to put the value at the 'end' of the array and decrease the manyItems counter (this is a variable for number of items in the array, because array.length is by default in the constructor 10.)
The code is largely written by another person. We had to import the existing files and write new methods to complete the task we were given. I have all the GUI part done so i will not include that class, only the used methods in the IntArrayBag class.
A second pair of eyes would be helpful. Thanks.
public class IntArrayBag implements Cloneable
{
// Invariant of the IntArrayBag class:
// 1. The number of elements in the bag is in the instance variable
// manyItems, which is no more than data.length.
// 2. For an empty bag, we do not care what is stored in any of data;
// for a non-empty bag, the elements in the bag are stored in data[0]
// through data[manyItems-1], and we don�t care what�s in the
// rest of data.
private int[ ] data;
private int manyItems;
public IntArrayBag( )
{
final int INITIAL_CAPACITY = 10;
manyItems = 0;
data = new int[INITIAL_CAPACITY];
}
public IntArrayBag clone( )
{ // Clone an IntArrayBag object.
IntArrayBag answer;
try
{
answer = (IntArrayBag) super.clone( );
}
catch (CloneNotSupportedException e)
{ // This exception should not occur. But if it does, it would probably
// indicate a programming error that made super.clone unavailable.
// The most common error would be forgetting the "Implements Cloneable"
// clause at the start of this class.
throw new RuntimeException
("This class does not implement Cloneable");
}
answer.data = data.clone( );
return answer;
}
public int size( )
{
return manyItems;
}
public boolean remove(int target)
{
int index; // The location of target in the data array.
// First, set index to the location of target in the data array,
// which could be as small as 0 or as large as manyItems-1; If target
// is not in the array, then index will be set equal to manyItems;
for (index = 0; (index < manyItems) && (target != data[index]); index++)
// No work is needed in the body of this for-loop.
;
if (index == manyItems)
// The target was not found, so nothing is removed.
return false;
else
{ // The target was found at data[index].
// So reduce manyItems by 1 and copy the last element onto data[index].
manyItems--;
data[index] = data[manyItems];
return true;
}
}
//I added extra variables that are not needed to try to increase readability,
//as well as when i was trying to debug the code originally
public boolean equals(Object obj){
if (obj instanceof IntArrayBag){
IntArrayBag canidate = (IntArrayBag) obj; // i know this can be changed, this was required
IntArrayBag canidateTest = (IntArrayBag) canidate.clone(); //this was created
//as a clone because it was otherwise referring to the same memory address
//this caused items to be removed from bags when testing for equality
IntArrayBag test = (IntArrayBag) this.clone();
//fast check to see if the two objects have the same number of items,
//if they dont will return false and skip the item by item checking
if (test.size() != canidateTest.size())
return false;
//the loop will go through every element in the test bag it will
//then remove the value that is present at the first index of the test bag
for (int i = 0; (i < (test.size()) || i < (canidateTest.size())); i++){
int check = test.data[i];
//remove() returns a boolean so if the value is not present in each bag
//then the conditional will be met and the method will return false
boolean test1 = test.remove(check);
boolean test2 = canidateTest.remove(check);
if (test1 != test2)
return false;
}//end for loop
// if the loop goes through every element
//and finds every value was true it will return true
return true;
}//end if
else
return false;
}//end equals
}
I cannot see the big picture, as I havent coded GUIs in Java before, however, as far as comparing 2 int[] arrays, I would sort the arrays before the comparison. This will allow you to eliminate problem cases like the one you stated ( if sorting is possible), then apply something like:
while(array_1[index]==array_2[index] && index<array_1.length)
{index++;}
and find where did the loop break by checking the final value of index
Is it explicitly stated to use clone? You can achieve it easily by overriding the hashCode() for this Object.
You can override the hashCode() for this object as follows:
#Override
public int hashCode() {
final int prime = 5;
int result = 1;
/* Sort Array */
Arrays.sort(this.data);
/* Calculate Hash */
for(int d : this.data) {
result = prime * result + d;
}
/* Return Result */
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || this.getClass() != obj.getClass()){
return false;
}
return false;
}
If you want to continue using your implementation for equals to compare test and CandidateTest then also you can compute unique hashes and make decision based on the results.
Here is the code snippet:
/* Assuming that you have put size comparison logic on top
and the two objects are of same size */
final int prime = 31;
int testResult = 1;
int candidateTestResult = 1;
for(int i = 0; i < test.size(); i++) {
testResult = prime * testResult + test.data[i];
candidateTestResult = prime * candidateTestResult + candidateTest.data[i];
}
/* Return Result */
return testResult == candidateTestResult;
I believe the problem is in this line:
for (int i = 0; (i < (test.size()) || i < (canidateTest.size())); i++){
The problem here is that test and canidateTest are the clones that you made, and you are removing elements from those bags. And any time you remove an element from the bag, the size will decrease (because you decrease manyItems, and size() returns manyItems). This means you're only going to go through half the array. Suppose the original size is 4. Then, the first time through the loop, i==0 and test.size()==4; the second time, i==0 and test.size()==3; the third time, i==2 and test.size()==2, and you exit the loop. So you don't look at all 4 elements--you only look at 2.
You'll need to decide: do you want to go through the elements of the original array, or the elements of the clone? If you go through the elements of the clone, you actually never need to increment i. You can always look at test.data[0], since once you look at it, you remove it, so you know test.data[0] will be replaced with something else. In fact, you don't need i at all. Just loop until the bag size is 0, or until you determine that the bags aren't equal. On the other hand, if you go through the elements of this.data (i.e. look at this.data[i] or just data[i]), then make sure i goes all the way up to this.size().
(One more small point: the correct spelling is "candidate".)
Maybe you should try SET interface
view this in detail :http://www.tutorialspoint.com/java/java_set_interface.htm
A set object cannot contains duplicate elements, so it's suitable for your assignment than build your own class.
For example:[1,1,2] and [1,2,2]
you can use this to test whether they are equal
arr1 = {1,1,2}
arr2 = {1,2,2}
Set<Integer> set = new HashSet<Integer>();
for(int i : arr1){//build set of arr1
if(set.contains(i)==false){
set.add(i)
}
}
for(int i:arr2){
if(set.contains(i)==false){
System.out.println('not equal');
break;
}
}
Hope this is helpful.

Recursively finding indexes of an INT in an ever-shrinking LispList

2nd-year Computer-Science student here, and as part of a set of exercises on recursion, we've been given some arbitrary problems to solve with LispLists. I'm stuck half-way through, so if anyone can point me in the right direction without explicitly giving me the answer, that would be great.
I need to find the positions of every instance of intToFind in the LispList listToCheck - the only conditions are that:
no additional arguments can be used
it has to be done recursively
For everyone who hasn't encountered LispLists - they don't have indexing, and the only methods you can call on them are:
.isEmpty() returns boolean
.head() returns the element at the 0th position
.tail() returns a LispList of all elements that aren't the head
.cons(value) adds value to the 'head' position - shifting everything else one down
There's also one method I wrote previously called:
recursiveCountLength(list) returns an int of the length of the passed LispList.
The list I've been testing on is: [2,3,4,2,5,12,2,5], so the result I'm looking for is [0,3,6] - with that out the way, here's what I've got so far (explanation of what I'm attempting after):
public static LispList<Integer>
recursivePositions(LispList<Integer> listToCheck, int intToFind)
{
if(listToCheck.isEmpty()) return listToCheck;
else {
// go through the array in its entirety once through,
// do everything else 'on the way back up'
LispList<Integer> positions = recursivePositions(listToCheck.tail(), intToFind);
//get the current length and current head
int currentInt = listToCheck.head();
int currentLength = recursiveCountLength(listToCheck);
//if a match is found, add the current length of the list to the list
if(currentInt == intToFind) return positions.cons(currentLength);
else return positions;
}
}
My current theory is that length of the array at each encounter of the int we're looking for (in this case 2) subtracted from the original length of the list (in this case 8) will give us the indexes.
2 first happens with a length of 8 (8-8 = index of 0, so indexes now [0]),
2 next happens with a length of 5 (8-5 = index of 3, so indexes now [0, 3]),
2 lastly happens at a length of 2 (8-2 = index of 6, so indexes now [0, 3, 6]).
The only problem is that I can't figure out how to get a static '8' - which leaves me to conclude that I'm approaching this in entirely the wrong way. Does anyone have any tips for me here? Any help would be hugely appreciated.
To clarify: a LispList is just a singly-linked-list (to differentiate from a Java LinkedList, which is double-linked).
Usually, you'd use a helper that carries information into the recursive calls, such as the current position and the positions already found (the current partial result).
LispList<Integer> positions (final int item, final LispList<Integer> list) {
return positionsAux( item, list, 0, new LispList<Integer>() );
}
private LispList<Integer> positionsAux (final int item,
final LispList<Integer> list,
final int position,
final LispList<Integer> result) {
if (list.isEmpty()) {
return result.reverse();
}
if (list.head().intValue() == item) {
result = result.cons(position);
}
return positionsAux( item, list.tail(), position + 1, result );
}
If that is not allowed, you need to carry the results backwards. If you assume that the recursive call has returned the correct result for your list.tail(), you need to add 1 to each found position to get the right result for your list. Then, you cons a 0 to the result if the current element matches. This version is less efficient than the first, because you traverse the current result list for every element of the input list (so it is O(n·m) instead of O(n), where n is the length of the input list and m the length of the result list).
LispList<Integer> positions (final int item, final LispList<Integer> list) {
if (list.isEmpty()) {
return new LispList<Integer>();
}
final LispList<Integer> tailResult = positions( item, list.tail() );
final LispList<Integer> result = tailResult.addToEach( 1 );
if (list.head().intValue() == item) {
return result.cons( 0 );
} else {
return result;
}
}
Implementing reverse() for the first version and addToEach(int) for the second is left as an exercise to the reader.
You need at least 3 arguments. Pretty sure adding more arguments is okay since he allows helper methods (because otherwise you could just make your method call the helper method which has more arguments).
Simplest way recursively:
public static LispList<Integer> positions(LispList<Integer> list, Integer key, Integer position){
if (list.isEmpty()) return LispList.empty();
if (list.head().equals(key)) return positions(list.tail(), key, position+1).cons(position);
return positions(list.tail(), key, position+1);
}

Getting indexoutofbounds exception in android

I'm getting an ArrayIndexOutOfBoundsException while removing postions because positions start from 1 but the array index starts from 0. Could you provide an explanation on how to solve this?
if (isChecked && groupName.equals(OLIConstants.FAILED_TO_ACTIVATE))
{
count = count + 1;
arrActivation.add(childPosition);
context.getSummaryFragment().getOli(arrActivation,groupPosition);
if (!context.getSummaryFragment().activateSystem.isEnabled())
{
context.getSummaryFragment().enableButton(true);
}
}
else if (!isChecked && groupName.equals(OLIConstants.FAILED_TO_ACTIVATE))
{
count = count - 1;
arrActivation.remove(childPosition);
}
context.getSummaryFragment().getOli(arrActivation,groupPosition);
if (context.getSummaryFragment().activateSystem.isEnabled() && count <= 0)
{
context.getSummaryFragment().enableButton(false);
}
}
I'm gonna make an assumption based on your code:
childPosition is the data you wanna store in ArrayList arrActivation.
arrActivation.add(childPosition);
childPosition is an integer (because you're getting an array index out of bound exception.
arrActivation.remove(childPosition);
Now, if you try to add an integer and remove it using the same parameter, you might get the AIOOB exception. Take a look:
ArrayList here = new ArrayList();
here.add(5);
// The following line will exception because
// The length of the array list is 1 at this point
here.remove(5);
But this will work:
ArrayList here = new ArrayList();
here.add(5);
// The following line will not exception
here.remove(Integer.valueOf(5));
Because now we're using the remove(Object o) (which finds the data with Object o, and remove the first occurance) function instead of the remove(int index) (which tries to remove the arraylist's index's index) function.
I hope this helps :)
You can access array by using arrActivation.add(childPosition-1);
Hope this will solve your issue.

Better way to find index of item in ArrayList?

For an Android app, I have the following functionality
private ArrayList<String> _categories; // eg ["horses","camels"[,etc]]
private int getCategoryPos(String category) {
for(int i = 0; i < this._categories.size(); ++i) {
if(this._categories.get(i) == category) return i;
}
return -1;
}
Is that the "best" way to write a function for getting an element's position? Or is there a fancy shmancy native function in java the I should leverage?
ArrayList has a indexOf() method. Check the API for more, but here's how it works:
private ArrayList<String> _categories; // Initialize all this stuff
private int getCategoryPos(String category) {
return _categories.indexOf(category);
}
indexOf() will return exactly what your method returns, fast.
ArrayList<String> alphabetList = new ArrayList<String>();
alphabetList.add("A"); // 0 index
alphabetList.add("B"); // 1 index
alphabetList.add("C"); // 2 index
alphabetList.add("D"); // 3 index
alphabetList.add("E"); // 4 index
alphabetList.add("F"); // 5 index
alphabetList.add("G"); // 6 index
alphabetList.add("H"); // 7 index
alphabetList.add("I"); // 8 index
int position = -1;
position = alphabetList.indexOf("H");
if (position == -1) {
Log.e(TAG, "Object not found in List");
} else {
Log.i(TAG, "" + position);
}
Output: List Index : 7
If you pass H it will return 7, if you pass J it will return -1 as we defined default value to -1.
Done
If your List is sorted and has good random access (as ArrayList does), you should look into Collections.binarySearch. Otherwise, you should use List.indexOf, as others have pointed out.
But your algorithm is sound, fwiw (other than the == others have pointed out).
Java API specifies two methods you could use: indexOf(Object obj) and lastIndexOf(Object obj). The first one returns the index of the element if found, -1 otherwise. The second one returns the last index, that would be like searching the list backwards.
There is indeed a fancy shmancy native function in java you should leverage.
ArrayList has an instance method called
indexOf(Object o)
(http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html)
You would be able to call it on _categories as follows:
_categories.indexOf("camels")
I have no experience with programming for Android - but this would work for a standard Java application.
Good luck.
the best solution here
class Category(var Id: Int,var Name: String)
arrayList is Category list
val selectedPositon=arrayList.map { x->x.Id }.indexOf(Category_Id)
spinner_update_categories.setSelection(selectedPositon)
Use indexOf() method to find first occurrence of the element in the collection.
The best way to find the position of item in the list is by using Collections interface,
Eg,
List<Integer> sampleList = Arrays.asList(10,45,56,35,6,7);
Collections.binarySearch(sampleList, 56);
Output : 2

Categories