For an assignment, we had to write a method sum that expects a List as a parameter. The method returns an int representing the sum of the integers in the list.
Would the code turn out to be:
public int getSum (List <Integer> list) {
int sum = 0;
for (int i = list)
sum = sum + i;
return sum;
}
I'm confused on when to use Integer vs int in this scenario. Thanks in advance!
Edit: If possible, could you guys edit my code?
No need to confuse. Your code seems correct to me. In java Wrapper classes are provided for premitive types. Java manages boxing/unboxing for those premitive type variable to their respective wrapper classes. e.g. Integer for int Long for long etc.
Usually Wrapper classes (Integer) turns to useful when considered for comparing object or to perform some class level operation such as equals() and hashCode() method, and also Collection framework require Object type not premitive type.
Integer is a Object/Wrapper Class int is a primitive type, Here is the link for you to understand more
Collections in java are generic class that you can use them to collect any object but not primary types. So you cannot use List<int>. If you are interested in using collections such as List, you have to use Integer.
public int getSum (List <Integer> list) {
int sum = 0;
for (int i : list)
sum = sum + i;
return sum;
}
Java collections use autoboxing concept. So for most cases you don't need to worry about the conversion. This is internally handled (i.e. from boxed to unboxed(primitive) type).
Below is the snippet:
public int getSum (List<Integer> list) {
int sum = 0;
for (int elem : list)
sum += elem;
return sum;
}
Related
I want to convert an array double[] to an immutable collection for use in a value object. However, I am dealing with a very large array and I keep getting the error java.lang.OutOfMemoryError: Java heap space.
I am currently using
Collections.unmodifiableList(DoubleStream.of(myArray).boxed().collect(Collectors.toList()));
I think it is because of this my program is running out of memory. Is there a cheaper way to convert double[] to an immutable list?
How about creating your own List<Double>? If you implement AbstractList<Double>, you'd only need to implement two methods for an unmodifiable list:
class MyDoubleList extends AbstractList<Double> implements RandomAccess {
private double[] backingArray;
public MyDoubleList(double[] backingArray) {
this.backingArray = backingArray;
}
#Override
public Double get(int index) {
return backingArray[index];
}
#Override
public int size() {
return backingArray.length;
}
// adding other list methods should be trivial...
}
Usage:
List<Double> list = new MyDoubleList(myBigDoubleArray);
Note that if you change the backing array, the list contents will change as well. To prevent this, you'd usually copy the array passed in, but since copying the array will probably cause an out of memory exception, I didn't do it.
Or if you use Guava, use Doubles.asList(myBigDoubleArray), which does essentially the same thing. Thanks to Joe for the suggestion!
Streams are great for functional programming, and readability but should be avoided when performance is the main concern. They create unnecessary extra objects.
Also surprisingly, arrays of the double primitive types consume more memory than their wrapper class Double arrays (ref: https://www.baeldung.com/java-primitives-vs-objects)
Use a Double object array instead of a double primitive, and then run:
Collection<Double> l = Collections.unmodifiableCollection(Arrays.asList(myArray));
I compared the 2 approaches like this
public static void main(String[] args) {
int len = 1000000;
Double[] myArray = new Double[len];
for (int i = 0; i < len; i++) {
myArray[i] = Math.random();
}
Collection<Double> l = Collections.unmodifiableCollection(Arrays.asList(myArray));
long totalMem = Runtime.getRuntime().totalMemory();
long usedMem = totalMem - Runtime.getRuntime().freeMemory();
System.out.println("totalMem="+humanReadableByteCountBin(totalMem));
System.out.println("usedMem=" + humanReadableByteCountBin(usedMem));
System.out.println("l has " + l.size() + " items ");
}
The stream approach used 48Mb, whereas Arrays.asList with Double uses 28Mb.
I just started OOP java and im struggling with getting a sum of my class type elements from an array. Can anyone help me?
hwComponents is a list type of a class HardwareComponent. Any help would be appreciated.
private Collection<HardwareComponent> hwComponents = new ArrayList<>();
public float calculatePrice()
{
float sum=0;
for (int i=1;i < hwComponents.size(); i++)
sum+= hwComponents.get(i); //The method get(i) is undefined for this type
return sum;
}
A Collection doesn't have a get(index) method.
Store your ArrayList in a List variable instead:
private List<HardwareComponent> hwComponents = new ArrayList<>();
Also note that the indices of your loop should begin at 0.
As an alternative, you can use an enhanced for loop, which doesn't require the get method:
for (HardwareComponent hc : hwComponents) {
sum+= hc.getSomeProperty(); // note that HardwareComponent cannot be added to
// a float (or to anything else for that matter, so you probably
// intended to call some method of your class which returns a float
}
If you don’t want to change the type of your array/collection, you just need to iterate through the collection in the collections defined order:
sum = 0;
for( HardwareComponent hc: hwComponents)
sum += hc.cost;
return sum;
So lets say I have a list, List<MyObject>, and a class MyObject as such:
public class MyObject {
Type t;
}
Where 't' is a non-unique identifier. How would I select all elements from my list with a specific value for t? For my purpose I am trying to return a count of how many objects in the list have a specific value for t.
I am assuming there is some clean way of doing this in Java without using an explicit loop?
Streams are your friend:
List<MyObject> list = ...;
long count = list.stream().filter(e -> e.getT().equals(<specific value>)).count();
You would of course need a way to access t, here I use getT() as an example.
If you don't want to use Java 8 use simple iteration as following:
int count(List<MyObject> list, Type x) {
int cnt = 0;
for(MyObject obj: list) {
if(obj.getT() == x) cnt++;
}
return cnt;
}
If you have List<Long> list, do you have to cast primitive longs to Long?
Do you have to do this
long l = -1;
list.add( (Long) l);
or will
list.add(l);
be fine and not cause any exceptions/errors?
I am assuming your java version is > 1.5 since you used generic list.
So in your case, list.add(l); will work
Don't be afraid to try such things on your local machine.
Read more here: Autoboxing and Unboxing
No you do not, the int primitives will be AutoBoxed
There is no need to cast primitive type long to object wrapper class Long compiler takes care of it. It is called Autoboxing.
As JavaDoc says : Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called unboxing.. Please refer
Consider the following code:
List<Integer> list = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
list.add(i);
Although you add the int values as primitive types, rather than Integer objects, to list, the code compiles. Because list is a list of Integer objects, not a list of int values, you may wonder why the Java compiler does not issue a compile-time error. The compiler does not generate an error because it creates an Integer object from i and adds the object to list. Thus, the compiler converts the previous code to the following at runtime:
List<Integer> list = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
list.add(Integer.valueOf(i));
The line return array[index1].compareTo(array[index2]); provides an error "Cannot invoke compareTo(double) on the primitive type double". How to solve this issue?
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*:: This function implements a comparator of double values :*/
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
private class ArrayIndexComparator implements Comparator<Integer>
{
private final double[] array;
public ArrayIndexComparator(double[] array)
{
this.array = array;
}
public Integer[] createIndexArray()
{
Integer[] indexes = new Integer[array.length];
for (int i = 0; i < array.length; i++)
{
indexes[i] = i; // Autoboxing
}
return indexes;
}
#Override
public int compare(Integer index1, Integer index2)
{
// Autounbox from Integer to int to use as array indexes
return array[index1].compareTo(array[index2]);
}
}
double[] dist = new double[centroids.size()];
// fill array...
ArrayIndexComparator comparator = new ArrayIndexComparator(dist);
Integer[] indexes = comparator.createIndexArray();
Arrays.sort(indexes, comparator);
Replace the call of an instance method compareTo with the call of static compare method, like this:
return Double.compare(array[index1], array[index2]);
This lets you keep your doubles in an array of primitives, and avoid autoboxing before calling an instance method.
In java primitive types don't have any methods. Instead using primitive data types use Wrapper classes.
change
return array[index1].compareTo(array[index2]);
to
return new Double(array[index1]).compareTo(array[index2]);
or
try with Double[] array; instead of double[] array;
for primitive types do not use compareTo, use == instead
but if you want to use compareTo just create a Double array
Double[] dist = new Double[centroids.size()];
Primitive Types cannot be compared directly by a comparator, as the interface is only implemented by collator and RuleBasedCollator. No wrapper class implements comparator. Due to which compiler won't be able to auto box it.
Just look in Double class and you will find an inbuilt method which provides compare method.
public static int compare(double d1, double d2)
Returns:
the value 0 if d1 is numerically equal to d2; a value less than 0 if d1 is numerically less than d2; and a value greater than 0 if d1 is numerically greater than d2.
Reverse: Multiple the entire expression by -1;