Java with ArrayLists the index of function - java

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.

Related

How can I tell if the elements in an Array List are same or different?

I'm trying to verify if all the elements in an array list are same or not. This is my code:
ArrayList<Integer> arr = new ArrayList<>(Arrays.asList(2,2,4,2));
for (int z = 0; z < arr.size(); z++) {
if(!arr.get(z++).equals(arr.get(z--))) {
System.out.println("same");
}else {
System.out.println("differnt");
}
}
Put the elements into a Set. If the resulting set has a size of 1, then all elements have been the same. One line of code, no loops, no indices, works with every collection:
boolean allTheSame = new HashSet<Integer>(list).size() == 1;
System.out.println(allTheSame ? "same" : "different");
(Edited:)
It might be worth noting that if the list is large, and likely contains many different elements, then constructing a Set will impose some memory overhead that can be avoided, if desired. In this case, you'd iterate over the list and compare all elements to the first one. But you should not check the elements for identity with ==. Instead, you should compare them using their equals method, or, if you graciously want to handle null entries, using Objects#equals.
An example of how to solve this efficiently and generically is given in the answer by Zabuza
There are various solutions to this.
Compare any with others
You just need to pick any element (the first, for example) and then compare this to all other elements. A single simple loop is enough:
public static <E> areElementsEquals(List<E> list) {
// Edge cases
if (list == null || list.size() <= 1) {
return true;
}
// Pick any element
E any = list.get(0);
// Compare against others
for (E other : list) {
// Use Objects#equals for null-safety
if (!Objects.equals(any, other)) {
return false;
}
}
return true;
}
Or a Stream-API version:
return list.stream()
.allMatch(other -> Objects.equals(any, other));
If you checked that any is not null, you could also use a method reference:
return list.stream()
.allMatch(any::equals);
Set
Sets do not have duplicates. You can put all your elements into a Set and check if the size is 1, then all other elements were duplicates.
return new HashSet<>(list).size() == 1;
While this code is pretty compact, I would favor the more straightforward solution of iterating. It is a bit more readable and also more efficient, since it does not have the additional overhead of setting up a set.
You only have to compare the 1st item against all the others:
int a = arr.get(0);
boolean allSame = true;
for (int z = 1; z < arr.size(); z++) {
allSame = (a == arr.get(z));
if (!allSame) break;
}
if (allSame)
System.out.println("Same");
else
System.out.println("Different");
. . . and does your code work? What sort of output do you get? Are you suffering any exceptions?
Don't declare your List as ArrayList; declare it as List. Don't call a List arr; it isn't an array. Call it numbers or something like that.
Why have you got the bang sign/not operator in line 3? I think that shouldn't be there.
If you think about the different kinds of collection/data structure available, which you can read about here, you will find a collection type whose size() method will tell you how many distinct elements you have.
You just have to compare the current element with the next, if they are different that means you don't have all elements the same:
for(int i = 0; i < list.size() - 1; i++) {
if (list.get(i) != list.get(i + 1)) {
return false; // elements are different
}
}
return true; // all element are the same
Try this :
String first = arr.get(0);
boolean allTheSame = true;
if (arr.size() > 1) {
for (int z = 1; z < arr.size(); z++) {
if (!arr.get(z).equals(first)) {
allTheSame = false;
break;
}
}
}
A method use BitSet to judge are all elements in list is same or not,it need less memory and run faster.
public static boolean areAllElementsSame(List<Integer> numbers) {
BitSet set = new BitSet();
numbers.forEach(new Consumer<Integer>() {
#Override
public void accept(Integer integer) {
set.set(integer);
}
});
return set.cardinality() == 1;
}
This method can also used to figure out how many different elements.
same is a flag that stores the result we intend.
uv is the uniformality variable.
Object is the type of object you stored in list (the arraylist)
import java.util.*;
class Main{
public static void main(String args[]){
ArrayList<Integer> arr = new ArrayList<>(Arrays.asList(2,2,2,2));
boolean same=true;
Object uv=arr.get(0);
for (Object i: arr){
if(!i.equals(uv)){
same=false;
break;
}
}
System.out.print("Result:"+same);
}
}
You will have to check for each element, if all the elements on later indexes are same as that one or different than it.
You can do it using a nested loop like this:
public static void main(String[] args) {
// write your code here
ArrayList<Integer> arr = new ArrayList<Integer>(Arrays.asList(2,2,4,2));
boolean result=true;
for (int i = 0; i < arr.size(); i++) {
for (int j=i; j<arr.size(); j++){
if (!arr.get(i).equals(arr.get(j))){
result=false;
}
}
}
System.out.println(result);
}
the 2nd loop starts from j=i and goes till the right end of the array because you don't need to check the left side of that index as it is already checked in the previous iterations and the result would already have been updated to false.
If you want to ensure that the list contains at least two different elements, you have to "walk" the array once: you compare the first element against all others, and stop on the first mismatch. On mismatch: not all elements are the same, otherwise they are all the same!
But the initial question was a bit unclear. If you want to determine if there are no two equal elements in the array, you have to compare all entries against all others! Then you need two loops: you pick all elemenst in order, to compare them to all others (respectively to all following ones: you already compared slot 1 to all other slots, so you would only have to compare slot 2 to slot3 ... til end).
Another approach would be to use a Set implementation, for example HashSet! Sets have unique members. So when you turn your list into a set, and the set has less entries than the list, you know that the list contains duplicates.

Java program to count positive values in a Collection<Integer>

I am working on a program to count the positive values in an integer Collection and having an issue. I am somewhat new to Java, and wondering if someone would be able to point out where I went wrong.
public class CountPositives {
/**
* Returns the number of positive values in the given Collection.
*/
public static int countPositives(Collection<Integer> collection) {
List<Integer> copy = new ArrayList(collection);
int positive = 0;
Iterator<Integer> itr = copy.iterator();
for (int i = 0; i < copy.size(); i++) {
if (copy.get(i) > 0 ) {
positive ++;
}
}
return positive;
}
}
Your code works fine for me. (Although you have an Iterator you never use) However..
Maybe an easier way would be to do:
return (int) copy.stream().filter(e -> e > 0).count();
Which will filter out all the non positive numbers and then return the count of them. Also you can simply use the passed Collection:
public static int countPositive(Collection<Integer> collection) {
return (int)collection.stream().filter(e -> e > 0).count();
}
Which will eliminate the copy List and the extra variables.
Note that count() returns a long. If the size of collection might exceed the limit of an int, you will want to change the return type to long and not cast to an int.
You're not using the Iterator. Collections can automatically give you an iterator, so there's no need to convert it to an ArrayList to get this.
Iterator<Integer> itr = collection.iterator();
Now you actually have to use it. The for statement may look wonky to you as a beginner, but remember that a for statement starts with an optional initialization step, which can be omitted.
for(; itr.hasNext();) {
Integer value = itr.next();
// rest of your logic here
}
If you prefer, you can initialize the iterator in the for statement directly.
for(Iterator<Integer> itr = collection.iterator(); itr.hasNext();) {
Integer value = itr.next();
// rest of your logic here
}
In spite of the wasteful copying, the code appears to be fine. The critical part of the code is checking to see if there are positive values, and your code does accomplish that. This is simply making it cleaner and less ceremonious.

Java - How to get item index from an array with its value?

If I have a array list say a string array, then how can I get index of an element with its value?
Code exammple:
private static final String[] TEST = new String[]{
"abc","bcd","def"
}
require its index with something like:
int i = TEST.getPosition("abc");/TEST.indexof(...);//not available
Also I tried with creating ArrayAdapter.
Is there anything like this? Or maybe I need to assign it with that adapter or something?
Or,
How can I get such index of an element?
Simplest idea:
Convert array to list and you can get position of an element.
List<String> abcd = Arrays.asList(yourArray);
int i = abcd.indexOf("abcd");
Other solution, you can iterator array:
int position = 0;
for (String obj : yourArray) {
if (obj.equals("abcd") {
return position;
}
position += 1;
}
//OR
for (int i = 0; i < yourArray.length; i++) {
if (obj.equals("abcd") {
return i;
}
}
You can refer to this question and use the Java 8 Lambda filter function.
Optional<String> optional = Arrays.stream(presents)
.filter(x -> "MyString".equals(x.getName()))
.findFirst();
if(optional.isPresent()) {//Check whether optional has element you are looking for
String s = optional.get();//get it from optional
}
the filter function take a lambda callback and will returns a list with only the values that match the condition in the lambda. In our case, we also want only the first one. That's why are add the findFirst() which will returns only the first value.
The function will returns an Optional, we can check if it contains a value using options.isPresent(). The optional.get() will returns the value.
Replace the "MyString" by your value and it should work.
If you wish to find an index, you can use the indexOf() function after changing your static array to an list : Arrays.asList(array);
There can be two methods which you can opt for -
1) First, as it is an array, you can simply run a for loop and compare using equals() and find the position.
2) Secondly, convert it into an List<> and run indexOf() and find the position.
NOTE: When you convert an array to List, it become a backed version List, it is fixed and size can't be alter --> but it is perfectly fine in your case as your array is final.
List<String> str = Arrays.asList(TEST);
int pos = str.indexOf("abc");
As others have said, the simplest method is Arrays.asList(TEST).indexOf("abc"). But here's an alternative using streams:
int index = IntStream.range(0, TEST.length)
.filter(i -> TEST[i].equals("abc"))
.findFirst()
.orElse(-1);

Adding Element to Middle of an Array (Data Structures)

I'm having trouble implementing an add method to an array structure for my data structures class and am not able to find a way to wrap my head around how to do this correctly. I am aware this is an impractical way handling data, but hey data structures.
Instructions:
The add method ensures that this set contains the specified element.
Neither duplicates nor null values are allowed. The method returns
true if this set was modified (i.e., the element was added) and false
otherwise. If the array is full, you must “resize” to an array twice
as large. Note that the constraint on the generic type parameter T of
the ArraySet class ensures that there is a natural order on the values
stored in an ArraySet. You must maintain the internal array in
ascending natural order at all times. The time complexity of the add
method must be O ( N ), where N is the number of elements in the set.
We are able to use the Array and Iterator classes only! Please do not give an answer using arraylists.
My Psudocode is:
Check element exists, check if array is full, if full double size,
compare elements to find an index where we can maintain natural order
and insert element or find the duplicate and exit, copy array from
top down and combine with inserted element and bottom part.
Actual Code:
//Given Fields
T[] elements;
int size;
//Add Method
public boolean add(T element) {
if (element != null) {
int index = -1;
int last_compare = -1;
for (int i = 0; i < size; i++) {
int compare = elements[i].compareTo(element);
if (compare > 0 && last_compare < 0) { //larger element, last element was smaller.
if (isFull()) {
resize(elements.length * 2);
}
index = i;
break;
} else if (compare == 0) {
return false;
}
last_compare = compare;
}
T[] temp = null;
//Need to copy the array here
} else {
return false;
}
}
I don't know how to insert this correctly while maintaining O(N) time complexity.
Any ideas?

How to get nth element of a Set

More specifically: how to get the nth element of a LinkedHashSet (which has a predictable iteration order)? I want to retrieve the nth element inserted into this Set (which wasn't already present).
Is it better to use a List:
List<T> list = new ArrayList<T>(mySet);
T value = list.get(x); // x < mySet.size()
or the toArray(T [] a) method:
T [] array = mySet.toArray(new T[mySet.size()]);
T value = array[y]; // y < mySet.size()
Other than the (likely slight) performance differences, anything to watch out for? Any clear winner?
Edit 1
NB: It doesn't matter why I want the last-inserted element, all that matters is that I want it. LinkedHashSet was specifically chosen because it "defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order). Note that insertion order is not affected if an element is re-inserted into the set."
Edit 2
This question seems to have devolved into a discussion of whether any Set implementation can ever preserve original insertion order. So I put up some simple test code at http://pastebin.com/KZJ3ETx9 to show that yes, LinkedHashSet does indeed preserve insertion order (the same as its iteration order) as its Javadoc claims.
Edit 3
Modified the description of the problem so that everybody isn't too focused on retrieving the last element of the Set (I originally thought that the title of the question would be enough of a hint — obviously I was wrong).
This method is based on the updated requirement to return the nth element, rather than just the last element. If the source is e.g. a Set with identifier mySet, the last element can be selected by nthElement(mySet, mySet.size()-1).
If n is small compared to the size of the Set, this method may be faster than e.g. converting to an ArrayList.
/**
* Return an element selected by position in iteration order.
* #param data The source from which an element is to be selected
* #param n The index of the required element. If it is not in the
* range of elements of the iterable, the method returns null.
* #return The selected element.
*/
public static final <T> T nthElement(Iterable<T> data, int n){
int index = 0;
for(T element : data){
if(index == n){
return element;
}
index++;
}
return null;
}
I'd use the iterator of the LinkedHashSet if you want to retrieve the last element:
Iterator<T> it = linkedHashSet.iterator();
T value = null;
while (it.hasNext()) {
value = it.next();
}
After the loop execution value will be referring to the last element.
So I decided to go with a slight variation of the answer by #Juvanis.
To get at the nth element in a LinkedHashSet:
Iterator<T> itr = mySet.iterator();
int nth = y;
T value = null;
for(int i = 0; itr.hasNext(); i++) {
value = itr.next();
if (i == nth) {
break;
}
}
Version 2 of the code:
public class SetUtil {
#Nullable
public static <T> T nthElement(Set<T> set, int n) {
if (null != set && n >= 0 && n < set.size()) {
int count = 0;
for (T element : set) {
if (n == count)
return element;
count++;
}
}
return null;
}
}
NB: with some slight modifications the method above can be used for all Iterables<T>.
This avoids the overhead of ensuring that a Set and a List stay in sync, and also avoids having to create a new List every time (which will be more time-consuming than any amount of algorithmic complexity).
Obviously I am using a Set to ensure uniqueness and I'd rather avoid a lengthy explanation as to why I need indexed access.
You can go with below solution,
here i have added object of ModelClass in HashSet.
ModelClass m1 = null;
int nth=scanner.nextInt();
for(int index=0;index<hashset1.size();index++){
m1 = (ModelClass) itr.next();
if(nth == index) {
System.out.println(m1);
break;
}
}
Set is unordered so the information on the last element inserted is lost. You cannot as such get the last element inserted. So don't use Set in the first place, or, if you really want to keep track of the last element, create a class containing that like this
class mySetAndLast extends Set{
T last;
Set<T> mySet;
}
now the question is what is the 'last element inserted'. Imagine your set was empty
-> insert x -> ok, x is the last inserted
-> insert y (y!=x) -> ok: y is the last inserted
-> insert x -> ?
is now x or y the last inserted?
x does not get inserted because y was the last element inserted and x already is an element of the set, on the other hand x from the user's point of view was the last inserted..
For your own, internal purpose, you could "hack" your own Set from any List implementation:
public class ListSet<E> extends ArrayList<E> implements Set<E> {
#Override
public boolean add(E item) {
return contains(item) ? false : super.add(item);
}
// ... and same for add(int, E), addAll(...), etc.
}
That example is slow (O(n) for an add) but, as you are the one implementing it, you can go back to it with smarter code for contains() based on your specifications.

Categories

Resources