I set an array of integer like below
int[] a = new int[11111];
//if I set
a[0] = 1;
a[1] = 2;
a[2] = 3;
a[3] = 4;
I want a method such that it gives me
4 but 11111.
Is there any method which I can use?
You should look into using an ArrayList
ArrayList<Integer> myList=new ArrayList<Integer>();
myList.add(1);
myList.add(2);
myList.add(3);
System.out.println("Size:"+myList.size());
Well, the following method will do what you asked for:
public int m() {
return 4;
}
On the assumption that you want a method that takes an array, and returns the greatest index that has been populated - you're right that the a.length only tells you the size of the array, i.e. the number of cells allocated.
This is going to be harder than you might expect, especially with an int array. Those unassigned cells are initialised to a value of 0. If you might actually use zero values in your array, then there is absolutely no way to tell whether the value in a cell is the "default" zero or one that you've set yourself.
If the array can't have zero values in it, then you'd need to loop over its entire length, checking for the highest index with a corresponding non-zero value; something like this:
public int dynamicLength(int[] a) {
int max = -1;
for (i = 0; i < a.length; i++) {
if (a[i] != 0) max = i;
}
return max;
}
Even then this might not be ideal, since arrays can be sparsely populated. Do you want the count of assigned indices, or the index of the highest assigned index?
The short answer is almost certainly "use an ArrayList".
When you do
int[] a = new int[11111]
It creates an array with 11111 elements and as it is int it will assign it to default value that is 0 so you have array with all values set.
You should move to List
You should use an ArrayList if the size of the array is changing. There is little performance difference.
See here for how to use one. See here for the API also.
I understand that you only want the assigned elements to be counted but it would be safer at runtime and simpler to use an ArrayList. The ArrayList class just wraps a Java array and handles the changing size for you. You can get the size by calling the size() method on the ArrayList.
See this example using a for-each loop if you want to iterate over the elements:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1); //size is 1
list.add(2); //size is 2
list.add(3); //size is 3
list.add(4); //size is 4
for(Integer n : list)
System.out.println(n);
An ArrayList uses an iterator and the for-each loop uses it to iterate over the ArrayList. Makes life much simpler.
As suggested above, using a List is probably the right answer. However, in the interest of solving the original problem, you could try this instead:
Integer[] foo = new Integer[11111];
foo[0] = new Integer(1);
foo[1] = new Integer(2);
foo[2] = new Integer(3);
foo[3] = new Integer(4);
and create a method that counts non-null values:
public static int countItems(Integer[] array) {
int count = 0;
for (Integer i : array) {
if (i != null) {
count++;
}
}
return count;
}
Of course, this will be a pain to manage as you would need to nullify any items no longer needed. It also raises the question of whether you would accept "holes" in your array, e.g. null values amongst non-null values. My example counting function above would accept such holes.
So, yes. Use a List.
You can create a method which calculates the non-0 elements of the array using a for/while loop.
Related
I've got a task of writing a function that returns integers which are in both two arrays.
For example: nums1 [1,2,3] and nums2 [2,3,5] and answer should be [2,3].
I came with this solution:
public static void main(String[] args) {
System.out.println(arraysIntersection(new int[] {1,2,3}, new int[] {2,3,5}));
}
public static List<Integer> arraysIntersection(int[] nums1, int[] nums2) {
List<Integer> answer = new ArrayList<>();
for (int i = 0; i < nums1.length; i++) {
if (Arrays.asList(nums2).contains(nums1[i])) {
answer.add(nums1[i]);
}
}
return answer;
}
however it seems this condition doesn't work as intended:
if (Arrays.asList(nums2).contains(nums1[i]))
It says it doesn't contain the value altough it clearly contains 2 and 3. Any ideas?
I know I could just iterate each i over the second array but I thought this solution would be faster. Does anyone knows why it's not working?
You can do it in O(NlogN) time complexity and O(n) memory. Just sort arrays and use two pointers technique.
List<Integer> answer = new ArrayList<>();
int j = 0;
Arrays.sort(nums1);
Arrays.sort(nums2);
for(int i = 0; i < nums1.length; i++) {
if(i > 0 && nums1[i] == nums1[i - 1]) //we have already processed this number
continue;
while(j < nums2.length && nums2[j] < nums1[i])
j++;
if(j < nums2.length && nums1[i] == nums2[j])
answer.add(nums1[i]);
}
return answer;
You can do it in O(N) time complexity and O(n) memory (but constant is higher). Just add all elements of nums1 in first HashSet and all elements of nums2 if another HashSet. Then you can for each element in first set check if another set contains this element using O(1)* time.
List<Integer> answer = new ArrayList<>();
Set<Integer> set1 = new HashSet<>(), set2 = new HashSet<>();
set1.addAll(nums1);
set2.addAll(nums2);
for(var el : set1) {
if(set2.contains(el)) {
answer.add(el);
}
}
return answer;
*O(1) is middle time of operations with hashset
If Arrays is a static object already initialized, or declared at global scope, it may be OK, I don't know for sure. Can't call asList() on an uninitialized object, it must be allocated first.
Now I know, Arrays is a member of the utils package, can be OK.
But not anything that looks fine in code, actually works also.
As a matter of fact, I don't like the way in which Java calls a function. But it would be more easier and handy like this.
I don't know, if you had included the util package in your code.
util, or utils ? Can be 2 different packages, this is important.
You can try another way:
import java.util.*;
public static List<Integer> arraysIntersection(int[] nums1, int[] nums2){
List<Integer> answer = new ArrayList<>();
for (int i = 0; i < nums1.length; i++) {
int u = nums1[i];
for (int j = 0; j < nums2.length; j++) {
if (u == nums2[j]) {
answer.add(u);
break;
}
}
}
return answer;
}
A break could be necessary, if the values must be added only once.
( a number can be found more times into an array )
The break was meant just for ending the inner loop.
The outer loop should continue up to the end of the search.
But the same number can be find more times in the first array.
Before returning the answer, the result should be checked for duplicate values. And this is another problem.
It would be more convenient to check before adding number to list.
Check if the answer list already contains the number value.
And then add the number to the list, if a match is not found.
So this can be done more easier:
if (!answer.contains(u)) answer.add(u);
Since you check this condition, the break is not anymore needed.
But searching the list so many times, can slow down your code.
From this reason, the u value is read only once, before starting to compare with the another array. So you don't have to read manytimes the same array item, just store it in a temporary variable, u.
In another point of view, when iterating over a collection object,
the current value for the current position index could change.
It also depends on the basic interface implementation for this object.
If this function would have been written in C, it would have been a very serious problem, to get the value of an item in array, because the current position of the pointer changes. And here is the same, the current read value changes, excepting that we can't see all the underlying mechanism. And if I am not wrong too much, the original Java first time was based also on the C code.
Best regards, Adrian Brinas.
Have a nice day.
I know that if I want to check if an array does contain a certain value I should use Arrays.asList(arrayName).contains(valueName).
But how do I check if that value is not present? At first I just thought of putting ! in front like:
!Arrays.asList(arrayName).contains(valueName)
but that doesn't seem to work.
I even tried writing the if statement like this:
if (Arrays.asList(arrayName).contains(valueName)==false)
but that doesn't seem to work either.
Here is the code:
public int[] duplikati(int[] tabela){
int len = tabela.length;
int c = 0;
int[] count = new int[len];
for (int i=0;i<len;i++){
if (Arrays.asList(count).contains(tabela[i])==false){
c++;
}
}
int[] result = new int[c];
int d = 0;
for (int j=0;j<len;j++){
if (Arrays.asList(result).contains(tabela[j])==false){
System.out.print(tabela[j]+" ");
result[d] = tabela[j];
d++;
}
}
return result;
}
In, this specific case when you pass an array of primitive types into Arrays.asList you'll get back a List with a single element which is the provided array.
So, when you do:
Arrays.asList(arrayName).contains(valueName)
The call Arrays.asList(arrayName) will return a List<int[]> and then when you call contains the valueName will get boxed to an Integer and then get's compared with the element(s) in the list. because an int[] is never equal to an integer value, the contains call will always return false.
Solution 1 - change the type of your arrays from int[] to Integer[], then everything should work as you expect.
Solution 2 - Assuming you do not want to change the type of the arrays for some reason, then you can do:
final int index = i;
if(Arrays.stream(count).noneMatch(e -> e == tabela[index])){...}
inside the for loops.
You can think of the noneMatch method as !Arrays.asList(someArray).contains(someValue) if it helps.
Similarly, you can check if the array contains an element with:
final int index = i;
if(Arrays.stream(count).anyMatch(e -> e == tabela[index])){...}
You can think of the anyMatch method as Arrays.asList(someArray).contains(someValue) if it helps.
You can use Java 8 stream api as follows
Integer arr[]=new Integer[]{1,2,30,61};
System.out.println(Arrays.asList(arr).stream().noneMatch(element>element==10));
You can go through the below link for explaination of
noneMatch()
I have an ArrayList. I would like to set each element of it to 0. Right now I have:
ArrayList <T extends Number> arr = new ArrayList();
for(int i = 0; i < some_other_array.size(); i++)
{
arr.add(0)
}
The compiler complains that
error: no suitable method found for set(int,int)
arr.add(0);
^
method ArrayList.set(int,T) is not applicable
(actual argument int cannot be converted to T by method invocation conversion)
where T is a type-variable:
T extends Number
It cannot be done. The method signature for is
public T ArrayList<T>.set(int index, T element)
Even though the constraint on T is that it extends Number, it does not mean that it can be constructed from a number.
Consider, for example,
class FortyTwo extends Number {
public byteValue() { return 42; }
public intValue() { return 42; }
// etc
}
What would you expect the initialization routine to do to an ArrayList<FortyTwo> ?
Just change your list declaration to
ArrayList<Number> arr = new ArrayList<Number>();
arr will be capable of holding anything extending Number (which is what you want, I assume).
Now, when you do
arr.set(i, 0)
that 0 will be autoboxed to an Integer. (See for yourself, add 0 and print arr.get(0) instanceof Integer.)
If you wanted to add doubles or longs for instance, you could use the literals 0d and 0L, respectively.
This should work for your case: arr.set(i, Integer.valueof(0));
Or you can reuse this handy standard API: Collections.fill(arr, Integer.valueof(0));
Why you want to set the value to 0, it will be automaticaly zero as ArrayList object will be instantiated. So the code will be useless as the size will be zero at the time so loop will not be executed.
Well, I think you're a little confused about how ArrayList actually works. When you create an ArrayList, it's always empty. Even if you specify a size:
ArrayList<Integer> arr = new ArrayList<Integer>(20);
That 20 just means "initial capacity", not "starting number of elements". As a result, set will never work because there are simply no elements. Even if you fix your compiler issue like this:
arr.set(i, Integer.valueOf(0));
Or like this:
ArrayList<Number> arr = new ArrayList<Number>();
It's not even going to do anything because arr.size() is zero, so the for loop won't even run.
The key here is that ArrayList is not an actual array. It wraps an array, and will expand its inner array when it has too many elements. In other words, I can't do this:
ArrayList<Integer> arr = new ArrayList<Integer>(20);
arr.get(0); // Throws an out of bounds exception
Now, that being said, if you want to start with 20 zeroes in your ArrayList, you can use the add method in your loop and i < 20 instead:
for(int i = 0; i < 20; i++) {
arr.add(Integer.valueOf(0));
}
This will add 20 zeroes to arr. Your code, even after fixing the error, will not.
Try changing the declaration of your ArrayList to
ArrayList<Integer> arr = new ArrayList<Integer>();
The Integer class supports auto-boxing, while the Number class does not. Also, the add() method may be more applicable.
You can try this (to the best of my knowledge, you cannot add primitive types to ArrayList):
ArrayList<Integer> arr = new ArrayList<Integer>();
for(int i = 0; i < someNumber; i++)
{
arr.add(0);
}
Remember that when size is 0 because it does not have any default values and the capacity is what you should be looking at (You can set the capacity in the constructor.)
I am getting some weird running times for my mergesort algorithm...I want to run the algorithm (say 1000 times) on the same permuted ArrayList. Right now, I just create an array of ArrayList of size 1000, then time how long it takes to sort each of these, then take the average of the times.
So my question is: am I sorting the same list over and over? If I change one instance of the ArrayList in the array say at index 0, will the other ArrayLists in the array stay the same? I would assume so, but I want to be certain that's not happening? Thanks.
for (int N = 1000; N <= 10000; N += 1000) {
//copy the array
#SuppressWarnings("unchecked")
ArrayList<Integer>[] container = (ArrayList<Integer>[])new ArrayList[N];
ArrayList<Integer> testArray1 = generatePermutedOrder(N);
for(int j=0; j<timesToLoop; j++){
container[j] = testArray1;
}
System.out.print(N + "\t");
// let things stabilize
startTime = System.nanoTime();
while (System.nanoTime() - startTime < 1000000000)
;
// time the routine
startTime = System.nanoTime();
for (int i = 0; i < timesToLoop; i++) {
mergesort(container[i]);
}
If I change one instance of the ArrayList in the array say at index 0, will the other ArrayLists in the array stay the same?
Yes, modifying ArrayList at index 0 won't effect the other indexes. (but make sure that other indexes don't have reference to same ArrayList)
Scenerio 1: (Modifying index 0 will effect index 1)
ArrayList[] arr = new ArrayList[2];
ArrayList aList = new ArrayList();
arr[0] = aList;
arr[1] = aList;
Scenerio 2: (Modifying index 0 will NOT effect index 1)
ArrayList[] arr = new ArrayList[2];
ArrayList aList1 = new ArrayList();
ArrayList aList2 = new ArrayList();
arr[0] = aList1;
arr[1] = aList2;
So, make sure it's Scenerio 2 in your code.
EDIT:
ArrayList<Integer> testArray1 = generatePermutedOrder(N);
for(int j=0; j<timesToLoop; j++)
{
container[j] = testArray1; // same reference pointing to same ArrayList is added in each interation
}
You are adding same reference to each index. So, modifying at any index will effect remaining indexes.
Yes the other ArrayList will stay the same.
For example.
array[0].set(0,object)
Will not affect the ArrayList at array[1]
You said you created an array of ArrayLists, but what did you assign into each slot in that array? Did you create one ArrayList instance and assign it to all 1000 slots in the array, or did you create 1000 different ArrayLists (e.g. using new in a loop) and assign a different one to each array slot?
If you store multiple references to the same object in multiple places, changes to that object will be visible through all the references.
If you just create an array of ArrayList objects they're all null. If you then iterate through the array and instantiate each ArrayList with new, then they're all different (each call to new ArrayList() will create a new one).
It's possible to put the same ArrayList reference in every element of the array by creating an ArrayList and then iterating through the array and assigning every element of the array the value of the (already created) ArrayList. This is probably not what you want to do.
I have an array for example:
String [][] test = {{"a","1"},
{"b","1"},
{"c","1"}};
Can anyone tell me how to remove an element from the array. For example I want to remove item "b", so that the array looks like:
{{"a","1"},
{"c","1"}}
I can't find a way of doing it. What I have found here so far is not working for me :(
You cannot remove an element from an array. The size of a Java array is determined when the array is allocated, and cannot be changed. The best you can do is:
Assign null to the array at the relevant position; e.g.
test[1] = null;
This leaves you with the problem of dealing with the "holes" in the array where the null values are. (In some cases this is not a problem ... but in most cases it is.)
Create a new array with the element removed; e.g.
String[][] tmp = new String[test.length - 1][];
int j = 0;
for (int i = 0; i < test.length; i++) {
if (i != indexOfItemToRemove) {
tmp[j++] = test[i];
}
}
test = tmp;
The Apache Commons ArrayUtils class has some static methods that will do this more neatly (e.g. Object[] ArrayUtils.remove(Object[], int), but the fact remains that this approach creates a new array object.
A better approach would be to use a suitable Collection type. For instance, the ArrayList type has a method that allows you to remove the element at a given position.
There is no built-in way to "remove" items from a regular Java array.
What you want to use is an ArrayList.
You could set the entry in the array to null (test[0][1] = null;). However, "removing" the item such that the array will have one element less than before is not doable without recreating the array. If you plan to change data in the data structure regularly an ArrayList (or another Collection class depending on your needs) might be more convenient.
My solution is:
You cannot remove an element from an array => it's correct, but we can do something to change current array.
No need assign null to the array at the relevant position; e.g.
test[1] = null;
Create a new array with the element removed; e.g.
String[][] temp = new String[test.length - 1][];
Need to get index at string/array to remove: IndexToRemove
for (int i = 0; i < test.length-1; i++) {
if (i<IndexToRemove){
temp[i]=test[i];
}else if (i==IndexToRemove){
temp[i]=test[i+1];
}else {
temp[i]=test[i+1];
}
}
test = temp;
Hope it helpful!