I must be missing something very obvious, but I've searched all over and can't find this method.
There are a couple of ways to accomplish this using the Arrays utility class.
If the array is not sorted and is not an array of primitives:
java.util.Arrays.asList(theArray).indexOf(o)
If the array is primitives and not sorted, one should use a solution offered by one of the other answers such as Kerem Baydoğan's, Andrew McKinlay's or Mishax's. The above code will compile even if theArray is primitive (possibly emitting a warning) but you'll get totally incorrect results nonetheless.
If the array is sorted, you can make use of a binary search for performance:
java.util.Arrays.binarySearch(theArray, o)
Array has no indexOf() method.
Maybe this Apache Commons Lang ArrayUtils method is what you are looking for
import org.apache.commons.lang3.ArrayUtils;
String[] colours = { "Red", "Orange", "Yellow", "Green" };
int indexOfYellow = ArrayUtils.indexOf(colours, "Yellow");
For primitives, if you want to avoid boxing, Guava has helpers for primitive arrays e.g. Ints.indexOf(int[] array, int target)
There is none. Either use a java.util.List*, or you can write your own indexOf():
public static <T> int indexOf(T needle, T[] haystack)
{
for (int i=0; i<haystack.length; i++)
{
if (haystack[i] != null && haystack[i].equals(needle)
|| needle == null && haystack[i] == null) return i;
}
return -1;
}
*you can make one from your array using Arrays#asList()
Unlike in C# where you have the Array.IndexOf method, and JavaScript where you have the indexOf method, Java's API (the Array and Arrays classes in particular) have no such method.
This method indexOf (together with its complement lastIndexOf) is defined in the java.util.List interface. Note that indexOf and lastIndexOf are not overloaded and only take an Object as a parameter.
If your array is sorted, you are in luck because the Arrays class defines a series of overloads of the binarySearch method that will find the index of the element you are looking for with best possible performance (O(log n) instead of O(n), the latter being what you can expect from a sequential search done by indexOf). There are four considerations:
The array must be sorted either in natural order or in the order of a Comparator that you provide as an argument, or at the very least all elements that are "less than" the key must come before that element in the array and all elements that are "greater than" the key must come after that element in the array;
The test you normally do with indexOf to determine if a key is in the array (verify if the return value is not -1) does not hold with binarySearch. You need to verify that the return value is not less than zero since the value returned will indicate the key is not present but the index at which it would be expected if it did exist;
If your array contains multiple elements that are equal to the key, what you get from binarySearch is undefined; this is different from indexOf that will return the first occurrence and lastIndexOf that will return the last occurrence.
An array of booleans might appear to be sorted if it first contains all falses and then all trues, but this doesn't count. There is no override of the binarySearch method that accepts an array of booleans and you'll have to do something clever there if you want O(log n) performance when detecting where the first true appears in an array, for instance using an array of Booleans and the constants Boolean.FALSE and Boolean.TRUE.
If your array is not sorted and not primitive type, you can use List's indexOf and lastIndexOf methods by invoking the asList method of java.util.Arrays. This method will return an AbstractList interface wrapper around your array. It involves minimal overhead since it does not create a copy of the array. As mentioned, this method is not overloaded so this will only work on arrays of reference types.
If your array is not sorted and the type of the array is primitive, you are out of luck with the Java API. Write your own for loop, or your own static utility method, which will certainly have performance advantages over the asList approach that involves some overhead of an object instantiation. In case you're concerned that writing a brute force for loop that iterates over all of the elements of the array is not an elegant solution, accept that that is exactly what the Java API is doing when you call indexOf. You can make something like this:
public static int indexOfIntArray(int[] array, int key) {
int returnvalue = -1;
for (int i = 0; i < array.length; ++i) {
if (key == array[i]) {
returnvalue = i;
break;
}
}
return returnvalue;
}
If you want to avoid writing your own method here, consider using one from a development framework like Guava. There you can find an implementation of indexOf and lastIndexOf.
Java ArrayList has an indexOf method. Java arrays have no such method.
I don't recall of a "indexOf" on arrays other than coding it for yourself... though you could probably use one of the many java.util.Arrays#binarySearch(...) methods (see the Arrays javadoc) if your array contains primitive types
The List interface has an indexOf() method, and you can obtain a List from your array with Array's asList() method. Other than that, Array itself has no such method. It does have a binarySearch() method for sorted arrays.
Arrays themselves do not have that method. A List, however, does:
indexOf
You're probably thinking of the java.util.ArrayList, not the array.
There is no direct indexOf function in java arrays.
Jeffrey Hantin's answer is good but it has some constraints, if its this do this or else to that...
You can write your own extension method and it always works the way you want.
Lists.indexOf(array, x -> item == x); // compare in the way you want
And here is your extension
public final class Lists {
private Lists() {
}
public static <T> int indexOf(T[] array, Predicate<T> predicate) {
for (int i = 0; i < array.length; i++) {
if (predicate.test(array[i])) return i;
}
return -1;
}
public static <T> int indexOf(List<T> list, Predicate<T> predicate) {
for (int i = 0; i < list.size(); i++) {
if (predicate.test(list.get(i))) return i;
}
return -1;
}
public interface Predicate<T> {
boolean test(T t);
}
}
int findIndex(int myElement, int[] someArray){
int index = 0;
for(int n: someArray){
if(myElement == n) return index;
else index++;
}
}
Note: you can use this method for arrays of type int, you can also use this algorithm for other types with minor changes
Related
I'm looking for an algorithm to fill an array of a specific size with the contents of a vararg, repeating the last element of the vararg until the array is full.
public static <T> T[] fillWithRepeat(int length, T... elements) {
// make array of length "length" and fill with contents of "elements"
}
Does anyone know a good algorithm for this?
As the question doesn't include any attempt of solving the problem itself, I assume homework, thus the answer is pseudo code only:
create a new array results of length length
iterate index from 0 to length
establish an index2 variable that runs from 0 to elements.length
assign ressult[index] = elements[index2]
either increase index2, or when it reaches elements.length-1, keep it at that value
For creating a "generic" array, see here.
And of course, user Hulk is correct (again), there are utility methods Arrays.fill() and for newer Javas Array.copyOf() that you should consider using.
Here's the algorithm. It also caters for the Generic instantiation problem when you will need to instantiate an array of type T
public static <T> T[] fillWithRepeat(int length, T... elements) {
List<T> output = new ArrayList<>(Arrays.asList(elements));
for(int i = 0; i < length - elements.length; i++){
output.add(elements[elements.length - 1]);
}
return output.toArray(elements);
}
I would like to pass different arrays of changing parameter types at different times into a method/function of which randomly returns one element, however am extremely struggling to do so using Java.
I have attempted to do so using the following code:
public int rndInx(Array theArray) {
theArray = theArray[(int)(Math.random() * theArray.length)];
return theArray;
}
However, Eclipse draws attention to errors; length not being resolved and the type of expression must be an array type. I assume one cause of the issue is the returnType, however I'm unsure what type would accept a range of returnTypes. I am aware that the syntax is probably extremely wrong too since I've only recently began to learn Java :(
For example, if I was to pass an array containing integers, then one random integer element would be returned - and if I was to pass an array containing strings etc. than one random element from the array in question would be returned.
Thanks in advance.
Here are the steps to achieve your end goal.
overload the method rndInx for int[] parameter, double[], long[] and so forth for however many primitive types you need to consider.
create a generic method for reference types
here is a hint for the generic method:
public <T> T rndInx(T[] theArray) {
return theArray[....]; // return the element at a random index
}
You can use a generic method:
public <T> T rndInx(T[] array) {
int index = (int)(Math.random() * array.length);
return array[];
}
But this won't work for primitive arrays. If you must accept primitive arrays, you'll have to use reflection and hope the caller has the right type:
public <T> T rndInx(Object array) {
int index = (int)(Math.random() * Array.getLength(array));
return (T)Array.get(array, index);
}
Or return Object and let the caller do the casting.
What you want is to use generics, e.g. like this:
public <T> T selectOneRandomly(T[] array) {
return array[(int)(Math.random() * array.length)];
}
This should work for anything except primitives like int, double etc.
For those you'd either have to provide special methods via overloads (e.g. int selectOneRandomly(int[] array)) or convert the arrays of primitives to arrays of wrapper types (i.e. int[] to Integer[]) before passing the converted arrays to your method.
An interview question was to write this method to remove duplicate element in an array.
public static Array removeDuplicates(Array a) {
...
return type is java.lang.reflect.Array and parameter is also java.lang.reflect.Array type.
How would this method be called for any array?
Also not sure about my implementation:
public static Array removeDuplicates(Array a)
{
int end=Array.getLength(a)-1;
for(int i=0;i<=end-1;i++)
{
for(int j=i+1;j<=end;j++)
{
if(Array.get(a, i)==Array.get(a, j))
{
Array.set(a, j, Array.get(a, end));
end--;
j--;
}
}
}
Array b=(Array) Array.newInstance(a.getClass(), end+1);
for(int i=0;i<=end;i++)
Array.set(a, i, Array.get(a, i));
return b;
}
You may want to consider using a different data structure such as a hashmap to detect the duplicate (O(1)) instead of looping with nested for loops (O(n^2)). It should give you much better time complexity.
There are various problem with this code. Starting here:
if(Array.get(a, i)==Array.get(a, j))
Keep in mind that those get() calls return Object. So, when you pass in an array of strings, comparing with == simply will most likely result in wrong results (because many objects that are in fact equal still have different references --- so your check returns false all the time!)
So, the first thing to change: use equals() instead of == !
The other problem is:
end--;
Seriously: you never ever change the variable that controls your for loop.
Instead: have another counter, like
int numberOfOutgoingItems = end;
and then decrease that counter!
For your final question - check the javadoc; for example for get(). That reads get(Object array, int index)
So you should be able to do something like:
int a[] = ...;
Object oneValue = Array.get(a, 0);
for example.
Disclaimer. I have to admit: I don't know if the Array implementation is smart enough to automatically turn the elements of an int[] into an Integer object.
It could well be that you have to write code first to detect the exact type of array (if it is an array of int for example); to instead call getInt() instead of getObject().
Beyond that, some further reading how to use reflection/Array can be found here
I know how to find minimum and maximum in an array. If a method lets say was called fMax():
public static double fMax(Object[] stuff)
The parameter is an array object how would I go about finding the max of this array? I cannot just do. Okay so how would I do this if I want the method to return a double and if the memory hasnt been allocated for the parameter named stuff then it will return the value NEGATIVE_INFINITY in the Double class, otherwise the return value will be the maximum value from the elements in the stuff array
Object max = stuff[0];
for (int i = 0; i < stuff.length; i++) {
if (data[i] > max) {
max = stuff[i];
}
}
To find the maximum of something, either
a) that something needs to implement the Comparable interface
b) you need to have some sort of explicit criteria for determining what maximum is, so you can put that in an instance of Comparator
Object itself isn't going to have anything useful for sorting. If you subclass object, you could sort based on the components of that object.
public class Example implements Comparable
{
int sortableValue = 0;
public Example (int value)
{
this.sortableValue = value;
}
public int compareTo(Example other)
{
return Integer.compare(this.sortableValue, other.sortableValue);
}
}
That's an object definition that has a natural sorting order. Java can look at that with any of the built in sorting algorithms and know the order they belong in.
If you don't provide java with a means of determining how an object has greater or lesser relative value compared to another object of the same type, it won't figure it out on its own.
Object is not comparable, you need a definite type if you want to compare values, sort or find something.
Streams are the most powerful, versatile tools for the job, this here will solve your problem if your want to find min/max of an array of Double :
Double[] arr = {1d, 2d, 3d, 4d};
Double min = Arrays.asList(arr).stream().parallel().min(Double::compare).get();
Double max = Arrays.asList(arr).stream().parallel().max(Double::compare).get();
String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class);
Now, just compare the new primitive array that we made from the object. If you don't need the object after this, and you aren't planning on returning an array object, then make your original array null, to take up less memory.
Check this:
How to compare two object arrays in Java?
I have a Sorts class that sorts (based on insertion sort, which was the assignment's direction) any ArrayList of any type passed through it, and uses insertion sort to sort the items in the list lexicographically:
public class Sorts
{
public static void sort(ArrayList objects)
{
for (int i=1; i<objects.size(); i++)
{
Comparable key = (Comparable)objects.get(i);
int position = i;
while (position>0 && (((Comparable)objects.get(position)).compareTo(objects.get(position-1)) < 0))
{
objects.set(position, objects.get(position-1));
position--;
}
objects.set(position, key);
}
}
}
In one of my other files, I use a method (that is called in main later) that sorts objects of type Owner, and we have to sort them by last name (if they are the same, then first name):
Directions: "Sort the list of owners by last name from A to Z. If more than one owner have the same last name, compare their first names. This method calls the sort method defined in the Sorts class."
What I thought first was to get the last name of each owner in a for loop, add it to a temporary ArrayList of type string, call Sorts.sort(), and then re-add it back into the ArrayList ownerList:
public void sortOwners() {
ArrayList<String> temp = new ArrayList<String>();
for (int i=0; i<ownerList.size(); i++)
temp.add(((Owner)ownerList.get(i)).getLastName());
Sorts.sort(temp);
for (int i=0; i<temp.size(); i++)
ownerList.get(i).setLastName(temp.get(i));
}
I guess this was the wrong way to approach it, as it is not sorting when I compile.
What I now think I should do is create two ArrayLists (one is firstName, one is LastName) and say that, in a for loop, that if (lastName is the same) then compare firstName, but I'm not sure if I would need two ArrayLists for that, as it seems needlessly complicated.
So what do you think?
Edit: I am adding a version of compareTo(Object other):
public int compareTo(Object other)
{
int result = 0;
if (lastName.compareTo(((Owner)other).getLastName()) < 0)
result = -1;
else if (lastName.compareTo(((Owner)other).getLastName()) > 0)
result = 1;
else if (lastName.equals(((Owner)other).getLastName()))
{
if (firstName.compareTo(((Owner)other).getFirstName()) < 0)
result = -1;
else if (firstName.compareTo(((Owner)other).getFirstName()) > 0)
result = 1;
else if (firstName.equals(((Owner)other).getFirstName()))
result = 0;
}
return result;
}
I think the object should implement a compareTo method that follows the normal Comparable contract--search for sorting on multiple fields. You are correct that having two lists is unnecessary.
If you have control over the Owner code to begin with, then change the code so that it implements Comparable. Its compareTo() method performs the lastName / firstName test described in the assignment. Your sortOwners() method will pass a List<Owner> directly to Sorts.sort().
If you don't have control over Owner, then create a subclass of Owner that implements Comparable. Call it OwnerSortable or the like. It accepts a regular Owner object in its constructor and simply delegates all methods other than compareTo() to the wrapped object. Its compareTo() will function as above. Your sortOwners() method will create a new List<OwnerSortable> out of the Owner list. It can then pass this on to Sorts.sort().
Since you have an ArrayList of objects, ordinarily we would use the Collections.sort() method to accomplish this task. Note the method signature:
public static <T extends Comparable<? super T>> void sort(List<T> list)
What's important here is that all the objects being sorted must implement the Comparable interface, which allows objects to be compared to another in numerical fashion. To clarify, a Comparable object has a method called compareTo with the following signature:
int compareTo(T o)
Now we're getting to the good part. When an object is Comparable, it can be compared numerically to another object. Let's look at a sample call.
String a = "bananas";
String b = "zebras";
System.out.println(a.compareTo(b));
The result will be -24. Semantically, since zebras is farther in the back of the dictionary compared to bananas, we say that bananas is comparatively less than zebras (not as far in the dictionary).
So the solution should be clear now. Use compareTo to compare your objects in such a way that they are sorted alphabetically. Since I've shown you how to compare strings, you should hopefully have a general idea of what needs to be written.
Once you have numerical comparisons, you would use the Collections class to sort your list. But since you have your own sorting ability, not having access to it is no great loss. You can still compare numerically, which was the goal all along! So this should make the necessary steps clearer, now that I have laid them out.
Since this is homework, here's some hints:
Assuming that the aim is to implement a sort algorithm yourself, you will find that it is much easier (and more performant) to extract the list elements into an array, sort the array and then rebuild the list (or create a new one).
If that's not the aim, then look at the Collections class.
Implement a custom Comparator, or change the object class to implement Comparable.