Java ArrayList search - java

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

Related

Returning Duplicates Arraylist

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)

Java for each statement

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.

Creating and filling an array in for each loop

//is there any way to do this
public Entry[] getArray(SimpleHashtable table) {
Entry[] data;
for (Entry k: table) {
//do something here
}
return data; //array that contains all elements stored in table
}
Is there a way to create and fill array with elements in for each loop?
Explained in short:
I have made class SimpleHashtable that stores objects, it implements Iterable.
Now I have to code method that returns an array of elements that are stored in that SimpleHashtable, and first idea that came to mind is to iterate over SimpleHashtable and fill array one element at the time, but I cant find any example of that.
If would like to avoid putting elements in a list in the meantime until I have iterated over SimpleHashtable (seems messy).
I know that arrays in Java aren't resizable, and that seems to make things difficult.
Assuming your class SimpleHashtable has a method size() to get the number of elements (which you need to size your array). You could then iterate with a for-each loop (as requested) with something like,
SimpleHashtable<Object> sh;
// ...
Object[] arr = new Object[sh.size()];
int pos = 0;
for (Object obj : sh) {
arr[pos++] = obj;
}

Getting Index of an item in an arraylist;

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.

Adding value to java array in the right place

I am trying to write a little program that will contain a array of profiles of people and I am stuck on the method for adding the profiles, as I would like them to be added in correct place so it doesn't need to be sorted. For example
If I have a array with 3 profiles
Potter, H
Smith, T
Warren, B
And I want to add Summer, P I would like it to be added right between the 1st and 2nd index
Before anyone asks I haven't got much code for this as I am still thinking on how to search the array and say where the profile needs to be placed.
Any ideas are appreciated
(Also it needs to be a Array not a ArrayList or any other data structure)
If you want to use an array rather than a decent, appropriate data structure, then use Arrays.binarySearch() to find the appropriate location. But you'll have to shift all the subsequent elements.
Whatever you are talking about is best done by the LinkedList http://docs.oracle.com/javase/6/docs/api/java/util/LinkedList.html
Since you want to use Array only, then as you know arrays have a constant number of elements that you declare. So I recommend you to create a temporary ArrayList and then copy those elements into an array that you want. Here how it's done
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
String[] yourInitialArray = { "Potter, H", "Smith, T", "Warren, B" };
// Creating a temporary ArrayList
ArrayList<String> temporary = new ArrayList<String>();
for (int i = 0; i < yourInitialArray.length; i++) {
if (i != 1) {
temporary.add(yourInitialArray[i]);
} else {
temporary.add("Summer, P");
temporary.add(yourInitialArray[i]);
}
}
yourInitialArray = new String[temporary.size()];
for (int j = 0; j < temporary.size(); j++) {
yourInitialArray[j] = temporary.get(j);
System.out.println(yourInitialArray[j]);
}
}
}
try to adding normally after that sort the list.It is better to use
First of all, I would highly recommend using the Collections framework List over the Arrays. because it provides the lot of flexibility and improvements over using normal arrays
and for your solution, i would recommend using the LinkedList. This provides the method add(int index, E element ) for inserting the element at specific location and it is very efficient

Categories

Resources