Sum of the elements ArrayList - java

I'm a beginner in Java and trying to get the sum of all the elements in the ArrayList. I'm doing it by using a method and get this error in the method:
"bad operand types for binary operator '+' first type: int, second
type: Object"
I don't know what I'm doing wrong here, appreciate any help!
public static int sumNumbers(<ArrayList> numbers){
int sum = 0;
for(int i = 0; i<numbers.size(); i++){
sum+=numbers.get(i);
}
return sum;
}

As others have pointed out, you need to give your ArrayList a type. You can then use native streams to make the code a little more compact:
ArrayList<Integer> numbers = ... ;
numbers.stream().mapToInt(i -> i).sum();

// create a list
List<Integer> ints = Arrays.asList(1, 2, 3);
// get the sum of the elements in the list
int sum = MathUtils.sum(ints);

Declare numbers as ArrayList<Integer> numbers.
Then the Integer will be unboxed to int. Right now, your arraylist contains objects that may not be ints.
For the moment, numbers.get() will return an object, and you can not add an object to an int directly.
You could always cast the element to Integer, but I would recommend the first option.

This will works fine.
import java.util.ArrayList;
public static int sumNumbers(ArrayList<Integer> numbers){
int sum = 0;
for(int i = 0; i<numbers.size(); i++){
sum+=numbers.get(i);
}
return sum;
}
Or
public static int sumNumbers(ArrayList<Integer> numbers){
return numbers.stream().mapToInt(n->n).sum();
}

Related

How to sort elements in an int array to create the largest number possible

I have an exercise to sort an array (type int) so I can get the largest number possible.
An example:
1,3,9 ==> 931
1,3,9,60 ==> 96031
So here is my idea: It is impossible to just sort the array to form the number that I wanted. So I can check the first number of each element in array, using the very same idea as bubble sort, just one small difference is that i use the first element to check instead of just arr[i]. But I still want to know beside using my idea, are there any other way (more efficiency). Even if your idea are the very same with my idea but you have something upgrade.
Thank you very much
It is impossible to just sort the array to form the number that I wanted.
Actually, it isn't impossible.
What you need is to design and implement an ordering that will result in the (decimal) numbers that will make the final number to be largest to sort first; e.g. for the numbers in your question, the ordering is:
9 < 60 < 3 < 1
You just need to work out exactly what the required ordering is for all possible non-negative integers. Once you have worked it out, code a Comparator class that implements the ordering.
Hint: You would be able to specify the ordering using recursion ...
Solution
For the descending order we multiply here by -1 each value in the array then sort the array and then multiply back with -1.
Ultimately we build the result string with string concatenation and print it out
import java.util.Arrays;
public class MyClass {
public static void main(String args[]) {
int[] array = {3,1,9};
for (int l = 0; l < array.length; l++){
array[l] = array[l]*-1;
}
Arrays.sort(array);
for (int l = 0; l < array.length; l++){
array[l] = array[l]*-1;
}
String res = "";
for(int i = 0; i < array.length; i++){
res+=array[i];
}
System.out.println(res);
}
}
Output
931
Alternatively
Or as #Matt has mentioned in the comments you can basically concat the string in reverse order. Then there is no need anymore for the ascending to descending transformation with *-1
import java.util.Arrays;
public class MyClass {
public static void main(String args[]) {
int[] array = {
9,
1,
3
};
String res = "";
Arrays.sort(array);
for (int l = array.length - 1; l >= 0; l--) {
res += array[l];
}
System.out.println(res);
}
}
Hope it will work as per your requirement->
public static void main(String[] args) {
Integer[] arr = {1,3,3,9,60 };
List<Integer> flat = Arrays.stream(arr).sorted((a, b) -> findfirst(b) - findfirst(a)).collect(Collectors.toList());
System.out.println(flat);
}
private static int findfirst(Integer a) {
int val = a;
if(val>=10) {
while (val >= 10) {
val = val / 10;
}
}
return val;
}
A lot of problems become easier when using Java streams. In this case you could convert all numbers to String and then sort in an order which picks the higher String value of two pairings, then finally join each number to one long one.
This works for your test data, but does NOT work for other data-sets:
List<Integer> list1 = List.of(1,3,9,60);
Comparator<String> compare1 = Comparator.reverseOrder();
String num1 = list1.stream().map(String::valueOf).sorted(compare1).collect(Collectors.joining(""));
The comparator Comparator.reverseOrder() does not work for numbers of different length which start with same values, so a more complex compare function is needed which concatenates values to decide ordering, something like this which implies that "459" > "45" > "451"
List<Integer> list2 = List.of(1,45,451,449,450,9, 4, 459);
Comparator<String> compare = (a,b) -> (b+a).substring(0, Math.max(a.length(), b.length())).compareTo((a+b).substring(0, Math.max(a.length(), b.length())));
String num2 = list2.stream().map(String::valueOf).sorted(compare).collect(Collectors.joining(""));
... perhaps.
compare first number of each int then if it is the biggest put it at beginning then you continue, if first char is equal step into the second etc etc the bigest win, if it same at max-char-size. the first selected would be pushed then the second one immediatly after as you already know.
In that maneer 9 > 60 cuz 960>609 the first char will always be the biggest in that case when u concat.
it's > 9 < not > 09 <

Initialize ArrayList with a range of integer values avoiding loops

I would like to initialize an ArrayList with a range of integer values.
This is what I want to avoid:
ArrayList<Integer> numbers = new ArrayList<>();
for(int i = 0; i < x; i++){
numbers.add(i);
}
I found rangeClosed function for IntStream:
IntStream.rangeClosed(0, instance.getNumVertices()-1);
But I think that the conversiont to ArrayList won't be worth it.
I'm looking for efficiency...
The ArrayList is backed by an array. If you want to fill it with ascending values, you won't get any quicker than just iterating over those values and adding them to the list.
The only thing I'd change in your example is initialize the array with the already known size, so that it wouldn't spend time and memory on expansion of the underlying array:
ArrayList<Integer> numbers = new ArrayList<>(x);
for(int i = 0; i < x; i++){
numbers.add(i);
}
List<Integer> range100 = IntStream.range(0,100).boxed().collect(Collectors.toList());
If you want to have an object that looks like a List<Integer> that contains numbers from 0 up to N without actually storing those numbers, then you can implement your own list, for example like this:
import java.util.AbstractList;
public class RangeList extends AbstractList<Integer> {
private final int size;
public RangeList(int size) {
this.size = size;
}
#Override
public Integer get(int index) {
return index;
}
#Override
public int size() {
return size;
}
}
You can create an instance of it like this:
List<Integer> numbers = new RangeList(10);
It behaves just like a standard ArrayList<Integer> containing the values 0 to 9, but you cannot modify the list (adding, removing, modifying entries will lead to an UnsupportedOperationException).
No matter how you decide to fill the ArrayList you will have to loop over or use each value that is stored into the ArrayList one by one. There is no faster way then iterating over each value and adding it to the ArrayList, only ways that make it look cleaner.
Creating a function that does so, or a an extension of the ArrayList object are two ways of doing so.
private ArrayList<Integer> fillRange(int min, int max){
ArrayList<Integer> a_lst = new ArrayList<>();
for(int i = min; i < max; i++){
a_lst.add(i);
}
return a_lst;
}

Trouble performing a deep copy of array

Need some advice for a project in an intro Java class. I'm stuck at creating a assignment constructor which takes an array as input and completes a deep copy. The constructor in question is found in the second block of code.
import java.util.Scanner;
public class NumberList
{
public static final int MAX_CAPACITY = 100;
private double [] numbers;
private int length;
public NumberList()
{
numbers = new double[MAX_CAPACITY];
int i;
for(i = 0; i < MAX_CAPACITY; i++)
numbers[i] = 0;
length = 10;
}
Everything before this line compiles. The constructor below is to complete a deep copy from the array parameter to the numbers array.
NumberList(final double a[])
{
double a[] = new double[MAX_CAPACITY];
numbers = a[];
}
Following errors received:
NumberList.java:67: error: '.class' expected
numbers = a[];
For the life of me, I cannot figure out how to do fix this. I've tried with a "for" loop, as well.
NumberList(final double a[])
{
double a[] = new double[MAX_CAPACITY];
numbers = a[];
}
The first line is attempting to re-declare the parameter a; you can't do that.
And the second line uses an invalid syntax: you never use [] except in the declaration of array variables, or the initialization of those variables.
The easiest way to copy a is to write:
numbers = Arrays.copyOf(a, a.length);
But you can write this with a loop like Mureinik shows you.
Note that you should write double[] a, not double a[]. The two are semantically identical, but the former is preferred because [] is part of the type, not the variable name.
The double a[]-style was put into Java "as a nod to the tradition of C and C++". You can read more here.
You can simply use:
NumberList(final double[] a) {
numbers = Arrays.copyOf(a, a.length);
}
Just run over a and copy its elements to numbers:
public NumberList(final double[] a) {
this.numbers = new double[a.length];
for (int i = 0; i < a.length; ++i) {
this.numbers[i] = a[i];
}
}

Displaying Average Integer in Array using Driver Program

I need practice with my syntax. I have an array of numbers and with that are methods to find the average, report highest number, and report the lowest number. To report the highest/lowest numbers I will be sorting the array.
But first my problem is with reporting the average. I think that if I can understand that part, then the min/max will be no problem. I have tried changing it to say Driver.randomArray[].getAverage() as well.
Are there any suggestions? Thanks in advance.
~Crystal
error code:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
randomArray cannot be resolved to a type
Class cannot be resolved to a type
Syntax error, insert ". class" to complete Expression
at IntegerArray.main(IntegerArray.java:48)
and it refers to my attempt to call the average from this line,
System.out.println(randomArray[].getAverage());
First, Driver Class
import java.util.Arrays;
public class Driver {
private static final int MAX = 0;
public Driver(){
int[] randomArray = new int [MAX];
int sum;
final int MAX;
}
public int getAverage(){
for (int index = 0; index < MAX; index++){
int sum = 0;
int[] randomArray = null;
int average;
sum = sum + randomArray[index];
average = sum/MAX;
return average;}
}
public void sortArray(){
// sort the array from smallest to biggest
int[] randomArray;
Arrays.sort(randomArray);
System.out.println("The sorted array from smallest to biggest is:");
for (int number : randomArray) {
System.out.println( + number)}
}
public int getMin(){
int[] randomArray;
// find the lowest number
return randomArray[0];
}
public int getMax(){
int[] randomArray;
// find the highest number
return randomArray[MAX];
}
}
Then my main class:
import java.util.Random;
import java.lang.reflect.Array;
import java.util.Arrays;
public class IntegerArray {
public static void main (String[] args) {
// set up the constant for the size of the array
final int MAX = 10;
int sum = 0;
int average = 0;
int[] randomArray = new int [MAX];
for (int index = 0; index < MAX; index++)
// values of the array go from 0-10
randomArray[index] = (int) (Math.random() *10);
// prints the array
for (int value : randomArray)
System.out.println (value);
System.out.println("The length of the array is: " + randomArray.length);
System.out.println(randomArray[].getAverage());
}
}
The way you're creating your methods eg. getAverage() you can't call it on the array you created. On the other hand you can call them on the a Driver object you create. for example: Driver driver = new Driver(); System.out.println(driver.getAverage()); If you want to call them on the Array Object you should add them on the Array class (but that is something more advanced Java than this).
In Java Code you need to add a ; after a statement don't forget them ;). Your IDE should warn you about them.
When you create your getMax() method you should add the array as a parameter. So that the method knows for what Array object it should get the highest number. For example:
public int getMax(int[] randomArray) {
// find the highest number
return randomArray[MAX];
}
This counts for all your methods.
I hope this solves some of your answers if not please add a comment or something.
So here is your code after that:
Driver class:
import java.util.Arrays;
public class Driver {
private static final int MAX = 0;
public Driver() {
int[] randomArray = new int[MAX];
int sum;
final int MAX;
}
public int getAverage() {
int average = 0;
for (int index = 0; index < MAX; index++) {
int sum = 0;
int[] randomArray = null;
sum = sum + randomArray[index];
average = sum / MAX;
}
return average;
}
public void sortArray(int[] randomArray) {
// sort the array from smallest to biggest
Arrays.sort(randomArray);
System.out.println("The sorted array from smallest to biggest is:");
for (int number : randomArray) {
System.out.println(+number);
}
}
public int getMin(int[] randomArray) {
// find the lowest number
return randomArray[0];
}
public int getMax(int[] randomArray) {
// find the highest number
return randomArray[MAX];
}
}
IntegerArray class:
public class IntegerArray {
public static void main(String[] args) {
// set up the constant for the size of the array
final int MAX = 10;
int sum = 0;
int average = 0;
int[] randomArray = new int[MAX];
for (int index = 0; index < MAX; index++)
// values of the array go from 0-10
randomArray[index] = (int) (Math.random() * 10);
// prints the array
for (int value : randomArray)
System.out.println(value);
System.out.println("The length of the array is: " + randomArray.length);
Driver driver = new Driver();
System.out.println(driver.getAverage());
}
}
Reply to the question in the comments:
You should give the randomArray as the parameter with your getAverage method so that method knows on which array it should operate, example: driver.getAverage(randomArray);
Your getAverage method also has some flaws:
1. Your sum variable should be outside the loop because else you would set your sum to 0 every time you iterate inside the loop.
2. int[] randomArray = null; You shouldn't really do this line at all, this line will create a NEW int array and set its value to null while you should you use the int array you give as a parameter.
So your getAverage method becomes:
public int getAverage(int[] randomArray) {
int sum = 0;
for (int index = 0; index < randomArray.length; index++) {
sum = sum + randomArray[index];
}
int average = sum / randomArray.length;
return average;
}
Currently your main class doesn't reference Driver at all, so your code cannot be called.
System.out.println(randomArray[].getAverage());
On this line randomArray is still just an array of integers (int[] randomArray = ...).
You will need to create an instance of Driver, pass in whatever array you're wanting to use, and then do .getAverage() on that.
randomArray is null and you are trying to read from a null array.
you need to define randomArray as a class member, not a local variable in all functions.
Local variables inside functions cannot be used as soon as function ends, and using the same name in other functions cannot help that.
Also:
define sum and average before loop. calculate and return average after loop.
Among other things your main issue seems to be a fundamental misunderstanding of scope rules. For example:
void method () {
int someVariable;
}
void method2 () {
someVariable = 2; // <-- Error.
}
In that code someVariable is local to method and is not available outside of it. You could not access it in method2.
I suggest you have a read not only of the above scope rules link, but of the official tutorial on member variables as well, which also describes scope. The information there will help you come up with a final strategy.
In your specific case your two most reasonable options are:
You could make randomArray a member field of your class (see above links).
You could pass randomArray as a parameter to your various methods (e.g. as a parameter to getAverage, see also the official tutorial on passing information to a method).
You have a few other issues, some mentioned in the other answers here, but my take is that is your primary confusion here. Read through the official tutorials (the docs.oracle.com links above), they're concise and well-written, and will fill in the blanks of some of your missing concepts. After you do that, give it another shot.
By the way, as for your compiler error on:
System.out.println(randomArray[].getAverage());
Unfortunately randomArray[].getAverage() simply does not make enough sense to justify a full explanation of how the compiler is interpreting it, so suffice it to say: No, that's wrong. :)
You'll want to check out that "passing information to a method" tutorial mentioned above, because it looks like you're trying to express something like this (option 2 above):
int getAverage (int randomArray[]) {
...
}
System.out.println(getAverage(randomArray));
As an aside: Note that the average of a bunch of integers isn't necessarily an integer itself (the average of 1 and 2 is 1.5). You might consider computing and returning a float or a double instead.

shortest way of filling an array with 1,2...n

Is there anything as quick as this in java? ( quick in coding)
int [] a = {1..99};
or I have to go for this:
int [] a=new int[100];
for (int i=0;i <100;++i){
a[i]=i;
}
Since Java 8 this is possible:
int[] a = IntStream.range(1, 100).toArray();
(And shorter than the other java 8 answer .).
Another alternative if you use Java 8:
int[] array = new int[100];
Arrays.setAll(array, i -> i + 1);
The lambda expression accepts the index of the cell, and returns a value to put in that cell. In this case, cells 0 - 99 are assigned the values 1-100.
Java 8 allows to do that in one line with IntStream object and lambda expression:
int n = 10;
int[] values = new int[n];
IntStream.range(1,n+1).forEach(val -> values[val-1] = val);
Out of curiosity, I have tested the performance of two versions of that method - one with a loop and the other one using guava:
public int[] loop() {
int[] a = new int[100];
for (int i = 0; i < 100; ++i) {
a[i] = i;
}
return a;
}
public int[] guava() {
Set<Integer> set = ContiguousSet.create(Range.closed(0, 99), DiscreteDomains.integers());
int[] a = Ints.toArray(set);
return a;
}
Here are the results:
Benchmark Mean Mean error Var Units
loop 79.913 5.671 30.447 nsec/op
guava 814.753 46.359 2034.726 nsec/op
So the guava() method runs in 814 ns +/- 46ns vs. 80 ns +/- 5ns for the loop() method. So loop() is about 10x faster. If you call that method a few times, the 800 nanoseconds don't matter, if you call it very often, writing the loop is probably better.
I think that your code is the shortest and the simplest way. You might dont need to load extra libraries to get more "compact" code lines. The for loops are very simple (a truly O(n)) and legible, live and love them.
depending on the size you will have to loop, if its a small one you can do the following...
int[] intArray = new int[] {4,5,6,7,8};
im guessing for your size you dont want to have to type it all out so makes sense to create a loop and set it that way
If people do want to use the for-loop method, then you could shorten it to (side note):
int [] a = new int[100];
for (int i = 0; i < 100; a[i] = i++);
You can use Guava library, for something like this:
public class Test {
public static void main(String[] args) {
//one liner
int[] array = toArray(newLinkedList(concat(range(1, 10), range(500, 1000))));
//more readable
Iterable<Integer> values = concat(range(1, 10), range(500, 1000));
List<Integer> list = newLinkedList(values);
int[] array = toArray(list);
}
public static List<Integer> range(int min, int max) {
List<Integer> list = newLinkedList();
for (int i = min; i <= max; i++) {
list.add(i);
}
return list;
}
}
Updated: full example take from this post Fill arrays with ranges of numbers
You must use loop to initialize such a long array. There is not a shortcut method in Java as you expected.

Categories

Resources