I have a Class called AuctionItem. The AuctionItem Class has a method called getName() that returns a String. If I have an ArrayList of type AuctionItem, what is the best way to return the index of an item in the ArrayList that has a specific name?
I know that there is an .indexOf() function. The parameter for this function is an object. To find the item that has a name, should I just use a for loop, and when the item is found, return the element position in the ArrayList?
Is there a better way?
I think a for-loop should be a valid solution :
public int getIndexByname(String pName)
{
for(AuctionItem _item : *yourArray*)
{
if(_item.getName().equals(pName))
return *yourarray*.indexOf(_item)
}
return -1;
}
Yes.you have to loop it
public int getIndex(String itemName)
{
for (int i = 0; i < arraylist.size(); i++)
{
AuctionItem auction = arraylist.get(i);
if (itemName.equals(auction.getname()))
{
return i;
}
}
return -1;
}
Basically you need to look up ArrayList element based on name getName. Two approaches to this problem:
1- Don't use ArrayList, Use HashMap<String,AutionItem> where String would be name
2- Use getName to generate index and use index based addition into array list list.add(int index, E element). One way to generate index from name would be to use its hashCode and modulo by ArrayList current size (something similar what is used inside HashMap)
.indexOf() works well.
If you want an example here is one:
ArrayList<String> example = new ArrayList<String>();
example.add("AB");
example.add("CD");
example.add("EF");
example.add("GH");
example.add("IJ");
example.add("KL");
example.add("MN");
System.out.println("Index of 'AB': "+example.indexOf("AB"));
System.out.println("Index of 'KL': "+example.indexOf("KL"));
System.out.println("Index of 'AA': "+example.indexOf("AA"));
System.out.println("Index of 'EF': "+example.indexOf("EF"));
will give you an output of
Index of 'AB': 0
Index of 'KL': 5
Index of 'AA': -1
Index of 'EF': 2
Note: This method returns -1 if the specified element is not present in the list.
for (int i = 0; i < list.length; i++) {
if (list.get(i) .getName().equalsIgnoreCase("myName")) {
System.out.println(i);
break;
}
}
To find the item that has a name, should I just use a for loop, and when the item is found, return the element position in the ArrayList?
Yes to the loop (either using indexes or an Iterator). On the return value, either return its index, or the item iteself, depending on your needs. ArrayList doesn't have an indexOf(Object target, Comparator compare)` or similar. Now that Java is getting lambda expressions (in Java 8, ~March 2014), I expect we'll see APIs get methods that accept lambdas for things like this.
You could implement hashCode/equals of your AuctionItem so that two of them are equal if they have the same name. When you do this you can use the methods indexOf and contains of the ArrayList like this: arrayList.indexOf(new AuctionItem("The name")). Or when you assume in the equals method that a String is passed: arrayList.indexOf("The name"). But that's not the best design.
But I would also prefer using a HashMap to map the name to the item.
Rather than a brute force loop through the list (eg 1 to 10000), rather use an iterative search approach :
The List needs to be sorted by the element to be tested.
Start search at the middle element size()/2 eg 5000
if search item greater than element at 5000, then test the element at the midpoint between the upper(10000) and midpoint(5000) - 7500
keep doing this until you reach the match (or use a brute force loop through once you get down to a smaller range (eg 20 items)
You can search a list of 10000 in around 13 to 14 tests, rather than potentially 9999 tests.
Related
is there a way with the index of function to return the index of a value that is part of a class like just one field of the bigger structure.. I got a simple contact class and I want to return the index when the id is a certain value .. should I be using a different structure than an arrayList it is doing most of what I want but the index of function is frustrating
I think the easiest way is to just iterate over the array, and check the condition with "if". That will be O(n).
You can use the Predicate method explained here.
Optional<Integer> indexOfMatch = IntStream.range(0, yourList.size())
.filter(i -> valueYouAreLookingFor.equals(yourList.get(i).getFieldYouAreChecking()))
.findFirst();
Or if the field holds a primitive value:
Optional<Integer> indexOfMatch = IntStream.range(0, yourList.size())
.filter(i -> valueYouAreLookingFor == yourList.get(i).getFieldYouAreChecking())
.findFirst();
If there is an element in the list that matches your predicate, indexOfMatch will have the index of that element. If not, indexOfMatch will be an empty Optional.
Regarding whether an ArrayList is the appropriate structure, generally if you are working with a list of values, an implementation of List is what you want. Whether it should be ArrayList or some other implementation depends on details of what you are doing with the list. For small list sizes, it often doesn't really matter which implementation you use.
well I switched to a vector from an array list but it did not really help but I did use a loop and the list size and just put the contact in a container each time so I could do my comparison it was kinda messy but I got the index that way.
static int SearchForContact(String ContactID) {
int temp = -1;
Contact searchCon;
for (int z = 0 ; z < contactVector.size(); z++)
{searchCon = contactVector.get(z);
if(searchCon.getId() == ContactID)
{temp = z;}
}
if (temp == -1) {
throw new IllegalArgumentException("Contact not found");
}
return temp;
}
I am iterating over the ArrayList and seeing whether the current value is the id value you want.
int yourValue = 25; //I am assuming it to be an int of value 25, you can keep it whatever you want.
for (int i = 0; i < yourArrayList.size(); i++)
{
if (yourArrayList.get(i) == yourValue)
{
return i; //returning the index value
}
}
return null; //this will run if the value doesn't exist.
Obviously, this would need to be inside a method that returns an integer that is the index. Above, yourArrayList is the ArrayList you are using, and yourValue is the value you need to find. It doesn't have to be an int.
Below is a simple for loop I am using to try and go through and find the repeated ID's in a array list. The problem is that it only checks one index to the right so quite clearly if there is the same ID two, three or even four indexes across it will miss it and not report it as a repeated ID.
Obviously the goal of this code is to move through each index of the array list, get the ID and check if there are any other identical ID's.
Note for the below arraylist is...arraylist, the getId method simply returns the user ID for that array object.
for (int i=0; i<arraylist.size()-1; i++) {
if (arraylist.get(i).getId() == arraylist.get(i+1).getId()) {
System.out.println(arraylist.get(i).getId());
}
}
What I've tried and keep coming back to is to use two embedded for loops, one for iterating through the array list and one for iterating through an array with userIDs. What I planned on doing is checking if the current arraylist ID was the same as the array with 'pure' IDs and if it wasn't I would add it to the array of 'pure IDs. It would look something like this in psudocode.
for i<-0 i<arraylist size-1 i++
for j<-0 j<pureArray size j++
if arraylist.getId(i) != pureArray[j] then
increment pureArray size by one
add arraylist.getId(i) to pureArray
In practice perhaps due to my poor coding, this did not work.
So any opinions on how I can iterate completely through my arraylist then check and return if any the gotten IDs have multiple entries.
Thank you.
Looking at leifg's answer on this similar question, you can use two sets, one for duplicates and one for everything else, and you can Set#add(E), which "returns true if this set did not already contain the specified element," to determine whether or not the element is a duplicate. All you have to do is change the sets generics and what you are adding to them:
public Set<Integer> findDuplicates(List<MyObject> listContainingDuplicates)
{
// Assuming your ID is of type int
final Set<Integer> setToReturn = new HashSet();
final Set<Integer> set1 = new HashSet();
for (MyObject object : listContainingDuplicates)
{
if (!set1.add(object.getID()))
{
setToReturn.add(object.getID());
}
}
return setToReturn;
}
For the purpose of getting duplicates, nested for loop should do the job, see the code below. One more thing is what would you expect this nested for loop to do.
Regarding your pseudocode:
for i<-0 i<arraylist size i++
for j<-i+1 j<arraylist size j++
if arraylist.getId(i) != arraylist.getId(j) then
add arraylist.getId(i) to pureArray
1) Regarding j<- i+1, with every iteration you do not want to compare the same thing many times. With this set up you can make sure you compare first with others, then move to second and compare it to the rest (not including first because you already did this comparison) etc.
2) Incrementing your array every single iteration is highly impractical as you will need to remap and create a new array every single iteration. I would rather make sure array is big enough initially or use other data structure like another ArrayList or just string.
Here is a small demo of what I did, just a quick test, far no perfect.
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
// create a test array with ID strings
ArrayList test = new ArrayList<>();
test.add("123");
test.add("234");
test.add("123");
test.add("123");
String duplicates = "";
for(int i = 0; i < test.size(); i++) {
for(int j = i+1; j < test.size(); j++) {
// if values are equal AND current value is not already a part
// of duplicates string, then add it to duplicates string
if(test.get(i).equals(test.get(j)) && !duplicates.contains(test.get(j).toString())) {
duplicates += " " + test.get(j);
}
}
}
System.out.println(duplicates);
}
}
Purely for the purpose of finding duplicates, you can also create a HashSet and iteratively add the objects(ID's in your case)to the HashSet using .add( e) method.
Trick with HashSet is that it does not allow duplicate values and .add( e) method will return false if the same value is passed.
But be careful of what values(objects) you are giving to the .add() method, since it uses .equal() to compare whatever you're feeding it. It works if you pass Strings as a value.
But if you're giving it an Object make sure you override .equals() method in that object's class definition (because that's what .add() method will use to compare the objects)
I'm really good with VB and I have a project where I need to check an array. If the same item in an array exists twice or more it needs to be changed to an item that doesn't exist. Now I'm in a class where they're making us use Java for this project.
I was wondering what is the equivalent of a for each loop in Java? I checked the JavaDocs and it only had info for the regular for loop, I didn't notice any section that said anything about a for each loop.
It's more subtle in Java than VB. You can find the official docs in the Oracle documentation here (towards the bottom):
Java For Loops
The provided example is:
// Returns the sum of the elements of a
int sum(int[] a) {
int result = 0;
for (int i : a)
result += i;
return result;
}
Hope that helps. Be careful not to remove or add elements inside the loop or you will get a Concurrent Modification Exception.
try
String arr [] = // you decide how this gets initialized
for (String obj: arr) {
}
This is called "iterating over collections". An array can be implicitly converted to a collection, so you can iterate over an array in the same way, using the "enhanced for-loop".
List<String> names = new LinkedList<>();
// ... add some names to the collection
for(name:names) {
System.out.println(name);
}
I'm not sure if VB has collections - they are a big part of Java and I recommend you look into them.
Of course this changes a bit in Java 8, although you'll notice a collection is still the backbone of forEach().
List<String> names = new LinkedList<>();
// ... add some names to the collection
names.forEach(name -> System.out.println(name));
A for each loop (also known as the enhanced for loop) is as follows:
for (String name : names) {
// here, the loop will work over each element of 'names',
// with the variable name with which to access each element
// being 'name', and output it
System.out.println(name);
}
A normal for loop is as follows:
for (int i = 0; i < max; i++) {
// here, i will iterate until max, then the loop will stop.
// any array access here has to be done manually using i, which increments.
}
If insertion order from the names array is important, keep adding the objects to a LinkedHashSet<String>, then with either a for loop or enhanced for loop or iterator, go over your list of names and add each of them to the LinkedHashSet. If the add method, passing in your name, returns false, generate a new name and add that.
If insertion order is not important, use a HashSet<String> instead.
At the end, convert back to an array if it is important (String[] bla = map.toArray(new String[0])), or output the toString() of the map.
I have a method called getLength
public int getLength(LinkedList<Boolean> numbers){
int length = numbers.size();
return length;
}
So it passes in a linked list of boolean values and names it numbers. What I'm trying to do is just get the length of the linked list, how many elements there are in it.
Am I using .size() correctly in that case?
Yes, .size() will return the number of items in the linked list:
http://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html#size()
On the Java API, we can read :
size() :
Returns the number of elements in this LinkedList.
So, I think that's what you want to get.
Source : http://developer.android.com/reference/java/util/LinkedList.html
I have an ArrayList of type String. I want to determine whether any element of this ArrayList starts with a specified string and if the ArrayList contains this element, then I want to get the index of this element. In addition, I do not want to loop this ArrayList to get the index of that element.
For example :
ArrayList<String> asd = new ArrayList<String>(); // We have an array list
//We filled the array list
asd.add("abcc trtiou");
asd.add("aiwr hiut qwe");
asd.add("vkl: gtr");
asd.add("aAgiur gfjhg ewru");
Now, I want to get the index of the element vkl: gtr by using vkl: without looping array list.(searching also should be case insensitive, so, using vkl: and VkL: should give the index of vkl: gtr)
How can I do this ?
Thanks in advance.
You have to loop the ArrayList. You cant possibly access just a single index and be guaranteed it is what you're looking for.
Also, you should consider using another data structure if a lot of searching is involved. Searching an ArrayList takes O(n)time while something like a red-black tree can be done in O(log n).
If you know before program execution the strings used to locate the items in the structure, consider using a HashMap. You can access the items in O(1).
If none of these solutions suit your particular problem expand on your answer with what you're trying to do, we could provide a better answer as to how you'd locate your items with minimal search time.
This is as far as you can get with your requirement if you're not looking to perform loop and search against the string objects held in the arraylist.
if(asd.contains("vkl: gtr"))
{
int index=asd.indexOf("vkl: gtr");
}
or simply:
int index = Arrays.binarySearch(asd.toArray(), 0, asd.size()-1, "vkl: gtr");
If performing loop in your calling method is what you're looking to avoid then, alternative you can create a class which extends ArrayList and have a method which does the index lookup.
class MyArray extends ArrayList<String>
{
public int getIndexOf(String o)
{
for (int i = 0; i < size(); i++)
{
if (get(i).contains((String) o)) return i;
}
return -(size() - 1);
}
}
Then from your calling program do:
public void foo()
{
MyArray asd = new MyArray();
asd.add("abcc trtiou");
asd.add("aiwr hiut qwe");
asd.add("vkl: gtr");
asd.add("aAgiur gfjhg ewru");
int index = asd.getIndexOf("vkl:");
}
for(int i=0; i < asd.size(); i++) {
String s = asd.get(i);
//search the string
if(found) {
return i
}
}
return -1
I don't really understand if you are looking for something like key-value pairs or single string entry search.
If you are looking for the first one you should use Map instead of a simple array if you want to search for a key
Here you can put a pair using
put(Object key, Object value)
and the getting the value of a specified key with
get(Object key)
If you are looing only for a quick way of finding a part of string into an array you have to read all indexes and compare strings one by one using stringToCompare.equalsIgnoreCase(otherStringToCompare). Note that this will throw an exception if stringToCompare is NULL