Various ways of accessing an array - java

Today i did learn two ways of accessing the array, i would like to know the various ways of accessing an array element and the best practice of it. I am a student learning algorithm.
int [] arr;
long [] arr;
Advantages of long datatype declaration over int.
class ArrayApp{
public static void main(final String[] args){
long [] arr;
arr= new long[2];
int i;
arr[0]=112;
arr[1]=111;
**// Way one**
for(long l:arr)
{
System.out.println(l);
}
**// Way Two**
for(i=0;i<arr.length;i++) {
System.out.println(arr[i]);
}
}
}

There is no real difference between the ways here. Way one is just a syntax sugar for not to create an additional interation value.
The first way is preferable as it doesn't require an int i; variable and requires less printing. The second should be used when you don't want to iterate through the all array, but just a part of it.
There is no other ways to access the elements of array in java.

We've one declaration of an array:
long[] values = new long[100];
This creates an array for 100 long type values. Each value has an index (position) inside the array, the first index (an int value!) is 0, the last one is 99.
The traditional for loop increments an integer value to generate index position numbers. Those int values are used to access the long values of the array:
for (int index=0; index < values.length; index++) { // index is int
long value = values[index]; // value is long
// do something with value
}
The "enhanced" for loop simply hides this index and gives access to the long values with less code:
for (long value:values) {
// do something with value
}
That's all. If you don't need the index variable in your code, just use the enhanced for loop (second version in my answer)

The first way
for(long l:arr)
{
System.out.println(l);
}
The java runtime will autobox the l to a Long, as iterating this way requires that the class implement the Iterable interface. This way, also does not provide the current index of the array.
The second way
for(i=0;i<arr.length;i++) {
System.out.println(arr[i]);
}
Requires no casts to Long and you also have access to the current index. You also however have to be careful about iterating past the end of the array or accessing array elements below 0.

An int is shorter as a long. You can make an array of any object or primitive type. int[], Integer[], CustomClass[], whatever.
From java documentation:
int: The int data type is a 32-bit
signed two's complement integer. It
has a minimum value of -2,147,483,648
and a maximum value of 2,147,483,647
(inclusive). For integral values, this
data type is generally the default
choice unless there is a reason (like
the above) to choose something else.
This data type will most likely be
large enough for the numbers your
program will use, but if you need a
wider range of values, use long
instead.
long: The long data type is a 64-bit
signed two's complement integer. It
has a minimum value of
-9,223,372,036,854,775,808 and a maximum value of
9,223,372,036,854,775,807 (inclusive).
Use this data type when you need a
range of values wider than those
provided by int.

Related

Finding common element in two arrays with best performing method

Implement a method that checks whether an integer is present in both integer array parameter 1 and integer array parameter 2 and prints the result of the search, with the best performance you can. The method parameters are: (1) the first integer array and (2) the second integer array of the same size as parameter 1 and (3) the integer to search for.
Note - Consider better performance to mean that a better performing method requires fewer general work steps to solve the problem with the same size of arrays. You may want to review the Java SE API page for java.util.Arrays
I was able to implement the solution but I am not sure if it the best-performing one because I am not using any java.util.Arrays methods as I am not sure which one to use necessarily to get me the best answer
public static void findCommonElements(int[] arr1, int[] arr2, int num){
for(int i = 0; i < arr1.length; i++){
for(int j = 0; j < arr2.length; j++){
if(arr1[i] == arr2[j] && arr1[i] == num){
System.out.println(num);
}
}
}
}
UPDATE:
I was able to update the code with following solution which completely removes for loop and implements binary for better performance
int[] arr1 = {7,8,5,1,2,3,6,7};
int[] arr2 = {9,8,6,4,1,2,4,5};
Arrays.sort(arr1);
Arrays.sort(arr2);
int index1 = Arrays.binarySearch(arr1, 5);
int index2 = Arrays.binarySearch(arr2, 5);
System.out.println(index1);
System.out.println(index2);
if(index1 < 0 || index2 < 0){
System.out.println("number not found in both arrays");
}
else{
System.out.println("number found in both arrays");
}
The problem description is a bit hard to follow, but by reference to the example code, I take this to be a fair rewording: "Write the best-performing method you can that takes two int arrays of the same length and a scalar int value i as parameters, and prints whether the value of i appears in both arrays."
Your first solution tests each pair of elements drawn one from the first array and the other from the second to determine whether they are equal to each other and to the target value. This is grossly inefficient for the problem as interpreted.
Your second solution sorts the arrays first, so as to be able to use a binary search to try to find the target element. This is better, but still inefficient. Although the binary searches are quite fast, the sorting required to prepare for them takes a lot more work than is saved by a single binary search.
Since it is sufficient to determine only whether the target value appears in both arrays, you can
scan each array for the target value, once, independently of the other.
skip the second scan if the first one does not find the target value
break early from each scan when the target value is found
The latter two are minor improvements, as they reduce only the minimum and average number of steps. The first, however, is a huge improvement, especially as array size increases, because for arrays of length n, then this requires a number of steps proportional to n in the worst case, whereas your first example code requires steps proportional to n2 in both the average and worst cases, and your second requires time proportional to n log n in the average and worst cases.
The implementation is left as the exercise it is intended to be. However, with respect to
I was able to implement the solution but I am not sure if it the
best-performing one because I am not using any java.util.Arrays
methods as I am not sure which one to use necessarily to get me the
best answer
, I don't think java.util.Arrays offers any method that particularly helps with this problem, especially given the orientation toward best possible performance.
You can use search the arrays using streams:
public static boolean findCommonElements(int[] arr1, int[] arr2, int num) {
return Arrays.stream(arr1).anyMatch(x -> x == num) &&
Arrays.stream(arr2).anyMatch(x -> x == num);
}
Similar method using linear search in arrays of Integer using Arrays.asList to convert arrays:
public static boolean findCommonElements(Integer[] arr1, Integer[] arr2, int num) {
return Arrays.asList(arr1).indexOf(num) > -1 &&
Arrays.asList(arr2).indexOf(num) > -1;
}

Iterate array if index range is in long

how to iterate through array/ list in Java. if index range is in long. As array/list only accept integer in position index.
eg
long arr[]=new long[5];
for(long i=0l;i<5l;i++)
arr[i]=i; // throw an error as arr[i] only accept integer
here arr[i] will throw an error because i is of type long and array takes input as integer in index location.
Can anyone help me out with this?
The size limit1 on arrays is Integer.MAX_VALUE so an array index that is a long makes no sense.
A List can have more than Integer.MAX_VALUE elements, but indexing it will be problematic because List::get takes an int argument.
So, you will struggle to use either arrays or lists (implemented using List) for really large data structures.
The solution ... if you really need one ... would be to implement your own List class with overload or alternative for operations that expose the size and indexing. It would not be trivial.
Another (possibly simpler) approach would be to represent your long[] as a long[][] and map the subscripts.
Finally, if you are using long as a subscript unnecessarily (i.e. the indexes don't need to go beyond Integer.MAX_VALUE), then:
long arr[] = new long[5];
for (long i = 0l; i < 5l; i++) {
arr[(int) i] = i;
}
1 - This is the theoretical maximum size. 1) You may get an OutOfMemoryError if you attempt to allocate an array that large. The JVM needs at least length * size(<type>) bytes of free contiguous storage to allocate an array of <type> of length length, where size(<type>) is the size of a primitive type or a reference. 2) In a 32 bit JVM, you are also limited by the address space dimensions. 3) In recent Hotspot JVMs, the largest array that you can allocate is actually Integer.MAX_VALUE - 5 elements: see Do Java arrays have a maximum size?
You don't need the index to be long even if your array consists of long's. Change it to
for(int i = 0; ....)
Two solutions:
Narrow the long to an integer by a cast arr[(int)i] = i;
Change the type of i to an integer and let the compiler widen it for you when it is assigned for(int i = 0; i < 5; i++) arr[i] = i;
As you cannot map all long values to a integer the compiler will not automatically narrow a variable. As you can map all integer values to a long the compiler will widen a variable automatically for you.

Why does using long instead of int give me different answer in the for loop(Longest Collatz sequence)

I am new to java programming language.
Why there are different output in this code?Can explain the problem to me?Thank you very much.
public class Collatz
{
public static void main(String[]arguments)
{ int max=0;
int real=0;
int a=0;
for (int i=2;i<1000000;i++)
{
real=i;
int count=1;
while(real>1)
{
if(real%2==0)
{
real=real/2;
}
else
{
real=3*real+1;
}
count++;
}
if(count>max){max=count;a=i;}
}
System.out.println(a+"&"+max);}
Output is 910107&476
public class Collatz
{
public static void main(String[]arguments)
{ long max=0;
long real=0;
long a=0;
for (int i=2;i<1000000;i++)
{
real=i;
int count=1;
while(real>1)
{
if(real%2==0)
{
real=real/2;
}
else
{
real=3*real+1;
}
count++;
}
if(count>max){max=count;a=i;}
}
System.out.println(a+"&"+max);}
Output is 837799&525
Can tell me what is the problem?Thank you.
For that you actually just need to look up the range of both variable types: http://www.cafeaulait.org/course/week2/02.html
To keep it simple: The value you are calculating here is most definitely too long for an Integer as it goes from -2,147,483,648 to 2,147,483,647 and that probably goes the same for long.
Because your value overflow the int (and long probably).
for (int i=2;i<1000000;i++){
real=i;
int count=1;
while(real>1)
You will loop a lot of time, especially with the logic in the while loop
Since you do a multiplication, the value will rise really fast and reach the maximum value and start back to the minimal ("bigger" negative value) and keep working with that.
Both int and long have a different maximum value, so the overflow occurs at different moment, giving a different result.
You can find the length of each primitive type here but following is the interesting part :
int: By default, the int data type is a 32-bit signed two's complement integer, which has a minimum value of -2^31 and a maximum value of 2^31-1. In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 2^32-1. Use the Integer class to use int data type as an unsigned integer. See the section The Number Classes for more information. Static methods like compareUnsigned, divideUnsigned etc have been added to the Integer class to support the arithmetic operations for unsigned integers.
long: The long data type is a 64-bit two's complement integer. The signed long has a minimum value of -2^63 and a maximum value of 2^63-1. In Java SE 8 and later, you can use the long data type to represent an unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 2^64-1. Use this data type when you need a range of values wider than those provided by int. The Long class also contains methods like compareUnsigned, divideUnsigned etc to support arithmetic operations for unsigned long.
For "unlimited" numerical value, you have the class BigInteger and BigDecimal but they are more expensive to use, so this will take some time to execute (perf vs precision is a choice)

Is there a difference in runtime efficiency if I evaluate the size of the array outside the loop?

The traditional way to iterate over an (integer, in this example) array of elements is the following:
int[] array = {5, 10, 15};
for(int i = 0; i < array.length; i++) [
//do something with array[i]
}
However, does this mean that after each iteration 'array.length' is re-evaluated? Would it not be more efficient to do this? :
int[] array = {5, 10, 15};
int noOfElements = array.length;
for(int i = 0; i < noOfElements; i++) {
//do something with array[i]
}
In this way, (to my understanding) the program only has to calculate it once and then look up the value of 'noOfElements' variable.
Note: I am aware of the enhanced for-loop, but it cannot be used when you want to use the variable that is being incremented ('i' in this example) to achieve other things within the for-loop.
I'm suspecting that this is actually a question of whether the Java compiler has the capability of realising that 'array.length' doesn't change and actually reusing that value after calculating it once.
So my question is: Is there a difference in runtime efficiency of the first block of code I wrote and the second one?
What I gather from the replies below, is that when an array is instantiated (is that the right word?) an instance variable called length is created and it is equal to the number of elements in the array.
What this means is that the statement array.length has nothing to do with calculation; it is only referencing the instance variable.
Thanks for the input guys!
See JLS- 10.7. Array Members:
The members of an array type are all of the following:
The public final field length, which contains the number of components
of the array. length may be positive or zero.
Calling array.length is O(1) (constant time operation - it's final member of the array).
Also note that as mentioned in the comments, "traditional" way is not necessarily the way you proposed. You can use for-each loop:
for(int i : array) {
...
}
length is a field, therefore is not calculated when examining the for loop condition.
Your second block of code introduces a field to represent the length, thus increases memory usage (slightly, but still an important factor).
Yet further, if the array were to be re-created/re-assigned at some point, with a different set of values, your field would not be updated, but the array's length field would.
length is a field of an array that is not being calculated if you call myArray.length, instead it is being set when you create the array. So no, it's not more efficient to save it to a variable before starting the for() loop.

create an array of long

I'm trying to create an array of long in java, but eclipse is showing me an error as shown below:
Below is my code:
How can I resolve this?
Can't i create a long size array in java?
Arrays of longs are fine: long[]. But all arrays are int-indexed. So just change long n to int n in the method parameter declaration, and you'll be all set.
For index you have to use int but not long
i need an array of 10^9 elements
You can create an array of one billion using an int value. Make n an int, and you can create an array with new long[n] Note: this will use 8 GB of heap.
Since you are building all the elements using a formula, you should be able to give all the values dynamically. i.e. create a component which is a "virtual" array which would save you having to generate an array of them all.
The reason I point this out is that the second loop is likely to take minutes at best if k is very small, or could easily take days.
BTW: I can't see all the code, but it appears you never need more than k+1 values which can be allocated once instead of n-k times.
n (the array capacity) has to be an integer not long
You have my sympathy. We go through this every time memory sizes increase. There is a strange expectation that this time array sizes will not need to increase in parallel with memory sizes.
Your best solution is probably to write your own class with long get(long index) and void set(long value, long index) methods. It could represent the data as a long[10][1000000000], and encapsulate the mapping between the natural long index and the actual pair of int indices.
Please note that array size is always equal to int size.
if you specify the array size more than 2147483647 you will get error.
long n;
long a[]=new long[n];
this will create error because long n exceeds 2147483647.
if int n then no error occurs.
import java.util.*;
public class Main
{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
long[] arr = new long[n];//Just declare the size of array of int type , because we cannot declare the size of array as long type ,rather we can store the long type in it ,This code will fix the error .
for(int i=0;i<n;i++)
{
arr[i]=sc.nextLong();
}
for(long i:arr)
{
System.out.print(i+" ");
}
}
}
The index needs to be int so I convert long to int.
long n = sc.nextLong();
long[] arr = new long[(int)n];

Categories