Java ArrayList<Double> as Parameter - java

I am currently working on a lab and would like to know how to handle the following problem which I have spent at least two hours on:
I am asked to create an ArrayList containing the values 1, 2, 3, 4 and 10. Whilst I usually never have any trouble creating an ArrayList with said values, I am having trouble this time. Should I create the ArrayList outside of the method or inside the method? Whichever way I have attempted it, I have been presented with numerous error messages. How do I add values to this ArrayList parameter? I have attempted to add values to it when calling it from the main method, but this still doesn't work. Here is the method in question.
public static double ScalesFitness(ArrayList<Double> weights){
//code emitted for illustration purposes
}
If anybody could help me it would be greatly appreciated. If any more code is required, then please let me know.
Thank you so much.
Mick.
EDIT: The code for the class in question is as follows:
import java.util.*;
public class ScalesSolution
{
private static String scasol;
//Creates a new scales solution based on a string parameter
//The string parameter is checked to see if it contains all zeros and ones
//Otherwise the random binary string generator is used (n = length of parameter)
public ScalesSolution(String s)
{
boolean ok = true;
int n = s.length();
for(int i=0;i<n;++i)
{
char si = s.charAt(i);
if (si != '0' && si != '1') ok = false;
}
if (ok)
{
scasol = s;
}
else
{
scasol = RandomBinaryString(n);
}
}
private static String RandomBinaryString(int n)
{
String s = new String();
for(int i = 0; i > s.length(); i++){
CS2004.UI(0,1);
if(i == 0){
System.out.println(s + "0");
}
else if(i == 0){
System.out.println(s + "1");
}
}
return(s);
}
public ScalesSolution(int n)
{
scasol = RandomBinaryString(n);
}
//This is the fitness function for the Scales problem
//This function returns -1 if the number of weights is less than
//the size of the current solution
public static double scalesFitness(ArrayList<Double> weights)
{
if (scasol.length() > weights.size()) return(-1);
double lhs = 0.0,rhs = 0.0;
double L = 0;
double R = 0;
for(int i = 0; i < scasol.length(); i++){
if(lhs == 0){
L = L + i;
}
else{
R = R + i;
}
}
int n = scasol.length();
return(Math.abs(lhs-rhs));
}
//Display the string without a new line
public void print()
{
System.out.print(scasol);
}
//Display the string with a new line
public void println()
{
print();
System.out.println();
}
}
The other class file that I am using (Lab7) is:
import java.util.ArrayList;
public class Lab7 {
public static void main(String args[])
{
for(int i = 0 ; i < 10; ++i)
{
double x = CS2004.UI(-1, 1);
System.out.println(x);
}
System.out.println();
ScalesSolution s = new ScalesSolution("10101");
s.println();
}
}

you can these
1) use varargs instead of list
public static double scalesFitness(Double...weights)
so you can call this method with :
scalesFitness(1.0, 2.0, 3.0, 4.0, 10.0);
2) create the list outside your method
ArrayList<Double> weights = new ArrayList<Double>();
weights.add(1.0);
weights.add(2.0);
weights.add(3.0);
weights.add(4.0);
weights.add(10.0);
scalesFitness(weights);

Towards your initial posting, this would work:
scalesFitness (new ArrayList<Double> (Arrays.asList (new Double [] {1.0, 2.0, 4.0, 10.0})));
You may explicitly list the values in Array form, but
you have to use 1.0 instead of 1, to indicate doubles
you have to prefix it with new Double [] to make an Array, and an Array not just of doubles
Arrays.asList() creates a form of List, but not an ArrayList, but
fortunately, ArrayList accepts a Collection as initial parameter in its constructor.
So with nearly no boilerplate, you're done. :)
If you can rewrite scalesFitness that would be of course a bit more easy. List<Double> as parameter is already an improvement.

Should I create the ArrayList outside of the method or inside the method?
The ArrayList is a parameter for the method so it need to be created outside the method, before you invoke the method.

You need to import ArrayList in the file that includes your methods. This is probably solved but that's the issue I was encountering.

Related

Return the result of each iteration in the loop

I'm doing something that produces the right result. However, it is wrong from a design POV.
The point of the program is to list the result of all the powers of a number up to and including the user-defined limit.
I have a constructor which accepts the base and the exponent from the Scanner. Then a method, which utilises a for loop to calculate the power for each exponent.
Now, the problem is that I'm printing the result from each loop iteration directly from this method. This beats the point of private variables and it being void in the 1st place.
Therefore, I want to define a getter method which returns the result of each power to the output. I used to set them just fine for if/switch statements, but I don't know how to do the same for loops. If I assign the result to a variable within the loop and return that variable from the getter then it will return only the output from the final iteration.
Private implementation
package Chapter6Review;
public class Powers {
private int target;
private int power;
public Powers(int target, int power) {
this.target = target;
this.power = power;
}
public void calculatePower() {
for (int i = 0; i <= power; i++) {
System.out.println((int) Math.pow(target, i));
}
}
/*
public int getPower() {
return
}
*/
}
User interface
package Chapter6Review;
import java.util.Scanner;
public class PowersTester {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter your base: ");
int target = in.nextInt();
System.out.print("Enter your exponent: ");
int power = in.nextInt();
Powers tester = new Powers(target, power);
tester.calculatePower();
}
}
You can simply use a List ;
public List<Integer> calculatePower() {
int p;
List<Integer> result = new ArrayList<Integer>();
for (int i = 0; i <= power; i++) {
p = (int) Math.pow(target, i);
result.add(p);
}
return result;
}
Then in you main method, you can iterate the list to print the powers like that :
List<Integer> result = new ArrayList<Integer>();
Powers tester = new Powers(target, power);
result = tester.calculatePower();
for (int i = 0; i < result.size(); i++) {
System.out.println(result.get(i));
}
You could store each of the results in a List:
List<Power> list = new ArrayList<>();
and when you call it add it as well
list.add(new Powers(target, power));
At the end you can iterate over the list like this:
for (Power power : list){
// your code
}
You might consider using streams as well
public List<Integer> calculatePower() {
return IntStream
.rangeClosed(0, power). // iterate from 0 till power inclusive
.mapToObj(i -> (int) Math.pow(target,i))
.collect(Collectors.toList()); // get result as list
}
Thanks for all the answers. Using a list seems to be a good choice.
Since I haven't covered lists yet, I resorted to this solution for now. But I don't like having code that can affect the solution in the main. Ideally, the loop should go in the private implementation.
Main
Powers tester = new Powers(target, power);
for (int i = 0; i <= power; i++) {
tester.calculatePower(i);
System.out.println(tester.getPower());
}
Private implementation
public void calculatePower(int iPower) {
result = (int) Math.pow(target, iPower);
}
public int getPower() {
return result;
}

JAVA Pass by reference error in method

I was trying to perform sorting of integers in an array and it worked fine.
But when i try to modify the program by including a "pass by reference" concept via a method, it is throwing error "cannot find symbol".
I am new to JAVA and learning by my own, Please help me with what I am doing wrong here.
import java.util.*;
import java.io.*;
public class Sort {
public static void main(String[] args) {
Sort obj = new Sort();
Scanner in = new Scanner(System.in);
int i, p, k, arr[];
arr = new int[10];
System.out.println("Enter the numbers for sorting \n");
for (i = 0; i < 5; i++) {
arr[i] = in.nextInt();
}
for (i = 0; i < 5; i++) {
for (p = 0; p < 5; p++) {
if (arr[i] < arr[p]) {
/*
* moving the below block for swapping to a new method. k =
* arr[i]; arr[i]= arr[p]; arr[p]= k;
*/
obj.swap(obj);
}
}
}
System.out.println("\n");
for (i = 0; i < 5; i++)
System.out.println(arr[i]);
}
public void swap(Sort m) {
m.k = m.arr[i];
m.arr[i] = m.arr[p];
m.arr[p] = m.k;
}
}
The error I am getting is :
"Sort.java:44: error: cannot find symbol
m.k = m.arr[i];
^
"
Similarly 10 such errors for other variables as well.
You are trying to use index variables (i and p) that don't exist in the context you are trying to use them (inside swap() method body) as well as members of Sort (k and arr) which don't exist. The scope of all these, you have limited to the method body of main():-
public void swap(Sort m) {
m.k = m.arr[i]; //No 'i' in swap(). No 'k' or 'arr' in 'm'(an instance of 'Sort')
m.arr[i] = m.arr[p]; //No 'p' in swap()
m.arr[p] = m.k;
}
Short-term Solution
Change your swap() method to
//Now accepting in i and p
public void swap(Sort m, int i, int p) {
m.k = m.arr[i];
m.arr[i] = m.arr[p];
m.arr[p] = m.k;
}
then call it like this
obj.swap(obj, i, p); //pass in i and p
and move your Sort variables to be accessible members of Sort
public class Sort {
public static int k; //now accessible with m.k
public static int[] arr = new int[10]; //now accessible with m.arr
...
}
Lastly, is it intentional that your array is 10 long but you only fill it with 5 numbers?
Pass-by-Reference
There is no "pass-by-reference" in Java. Everything is passed by value. The confusing thing is that what is passed by value is technically a reference to the object, meaning you get strange effects like you can edit the object but not reassign it.
Solution: move the stuff back from the swap method to where it was.
Alternatively, provide the necessary values as parameters to swap.

How to call and declare a method with a variable amount of arguments?

I'm hopelessly trying to call a function with (int = amountCoefficients) amount of arguments, and declaring a function with that amount of arguments too.
What makes it harder is that for example amountCoefficients = 5, then it means that there's an array of 5 blocks that each have a value (double). So the first argument would have to be equal to the value of the first block of that array, the second argument would have to be equal to the value of the second block of that array etc.
And beforehand we don't know how many arguments we need, as that depends on the amount of doubles that are filled in by the user, so amountCoefficients could be equal to 2, 4, or any other positive integer.
I'm pretty new to Java and I really don't have no idea what to do. As you can see below I tried to do something with a for loop, but I don't think that works.
public class Interpol {
public static void main(String []args) {
Scanner scanner = new Scanner(System.in);
//acquire user input (polynomial coefficients and interval values x1 and x2)
ArrayList<Double> polynomialCoefficients = new ArrayList<Double>();
int amountCoefficients = 0;
while (scanner.hasNextDouble()) {
polynomialCoefficients.add(scanner.nextDouble());
amountCoefficients++;
}
String in = scanner.next();
double x1 = scanner.nextDouble();
double x2 = scanner.nextDouble();
//call method f to determine the polynomial function
int i = 0;
for (i = 0; i < amountCoefficients; i++) {
f
}
//call method findaroot to determine the root
//print result
}
}
public static double f(double x) {
//function of which a root is to be found
}
You can create a method that takes a list or array. Then the method can use List.size() and array.length to process every object.
public static void main(String[] args){
ArrayList<Double> polynomialCoefficients = new ArrayList<Double>();
// get data
...
process(polynomialCoefficients);
}
public void process(List<Double> coefficients){
for(int i = 0; i < coefficients.size(); i ++){
System.out.println("Element " + i + ": " + coefficients.get(i));
}
}
You can use the VarArgs notation to receive an arbitrary amount of parameters, although they will be converted into an array. This is achieved by a code like the following:
public void printOneEachLine(String... parameters) {
for (String parameter : parameters) {
System.out.println(parameter);
}
}
And you can call it with:
printOneEachLine("msg1", "msg2");
printOneEachLine("msg3", "msg4", "msg5", "msg6");

Getting error for the product of items in an array

I want to take inputs from console and use the numbers in performing calculations. I want to stop receiving items into array when i receive some ref value like"10"(in this case) from console. As soon as i enter 10 in console the array has to be ended and the values in array have to be multiplied. I have tried this as a program but am getting 0 as answer for the product being performed.
public class Scrap {
private static int i;
private static double[] as;
public static void main(String[] args)
{
as=new double[100];
for(i=0;i<as.length;i++)
{
as[i]=dscan();
if(as[i]==10)
break;
}
double d=1;
for(i=0;i<as.length;i++)
{
d=d*as[i];
}
System.out.println("Product is :"+(d/10));
}
public static double dscan()
{
System.out.print(" : ");
return new Scanner(System.in).nextDouble();
}
}
In your case as=new double[100]; will initialize array with 100 zeros (default value for primitive double) and as.length will always return 100 (the size of initialized array) and not the number of valid elements, so if you enter less than 100 values the rest will remain zeros, which will be used for multiplication..
To make it work you either need to count the number of valid elements in a separate variable and then use it restrict your array window or as Matej sugests use a dynamically sized collection.
this code works ... i improved it to use List instead of array , because at start you dont know how many inputs you will have ... if you dont understand anything , just ask ...
public class Scrap {
private static int i;
private static ArrayList<Double> al = new ArrayList<Double>();
public static void main(String[] args) {
while (true) {
double d = dscan();
if (d != 10) {
al.add(d);
}else{
break;
}
}
double d = 1;
for (i = 0; i < al.size(); i++) {
d = d * al.get(i);
}
System.out.println("Product is :" + (d / 10));
}
public static double dscan() {
System.out.print(" : ");
return new Scanner(System.in).nextDouble();
}
}

How to display object as a String properly

Im working on this code and expecting a matrix to be printed but thats what came up
Matrix#2c78bc3b Matrix#2a8ddc4c
This is a code example:
public class Matrix
{
public static int rows;
public static int colms;//columns
public static int[][] numbers;
public Matrix(int[][] numbers)
{
numbers = new int[rows][colms];
}
public static boolean isSquareMatrix(Matrix m)
{
//rows = numbers.length;
//colms = numbers[0].length;
if(rows == colms)
return true;
else
return false;
}
public static Matrix getTranspose(Matrix trans)
{
trans = new Matrix(numbers);
for(int i =0; i < rows; i++)
{
for(int j = 0; j < colms; j++)
{
trans.numbers[i][j] = numbers[j][i];
}
}
return trans;
}
public static void main(String[] args)
{
int[][] m1 = new int[][]{{1,4}, {5,3}};
Matrix Mat = new Matrix(m1);
System.out.print(Mat);
System.out.print(getTranspose(Mat));
}
}
You need to implement toString() in a meaningful way.
This toString() (below) is perhaps suitable for debugging, but will be ugly and confusing if you use it for real user output. An actual solution would probably use a Formatter in some complicated way to produce neatly tabular rows and columns.
Some additional recommendations based on your code:
Suggest not storing the rows/columns sizes separately. SSOT / Single Source of Truth or DRY, Java+DRY. Just use the .length, and provide accessor methods if need be.
Use final in method args, it will eliminate bugs like you have above, aliasing numbers incorrectly int the constructor
Use an instance, not static
Paranoia is the programmer's lifestyle: I also modified my code to do a deepCopy of the provided int[][] array, otherwise there is reference leakage, and the Matrix class would be unable to enforce its own invariants if caller code later modified the int[][] they passed in.
I made my Matrix immutable (see final private numbers[][]) out of habit. This is a good practice, unless you come up with a good reason for a mutable implementation (wouldn't be surprising for performance reasons in matrices).
Here's some improved code:
public final class Matrix
{
final private int[][] numbers;
// note the final, which would find a bug in your cited code above...
public Matrix(final int[][] numbers)
{
// by enforcing these assumptions / invariants here, you don't need to deal
// with checking them in other parts of the code. This is long enough that you might
// factor it out into a private void sanityCheck() method, which could be
// applied elsewhere when there are non-trivial mutations of the internal state
if (numbers == null || numbers.length == 0)
throw new NullPointerException("Matrix can't have null contents or zero rows");
final int columns = numbers[0].length;
if (columns == 0)
throw new IllegalArgumentException("Matrix can't have zero columns");
for (int i =1; i < numbers.length; i++) {
if (numbers[i] == null)
throw new NullPointerException("Matrix can't have null row "+i);
if (numbers[i].length != columns)
throw new IllegalArgumentException("Matrix can't have differing row lengths!");
}
this.numbers = deepCopy(numbers);
}
public boolean isSquareMatrix() { return rowCount() == columnCount(); }
public int rowCount() { return numbers.length; }
public int columnCount() {return numbers[0].length; }
private static int[][] deepCopy(final int[][] source)
{
// note we ignore error cases that don't apply because of
// invariants in the constructor:
assert(source != null); assert(source.length != 0);
assert(source[0] != null); assert(source[0].length != 0);
int[][] target = new int[source.length][source[0].length];
for (int i = 0; i < source.length; i++)
target[i] = Arrays.copyOf(source[i],source[i].length);
return target;
}
public Matrix getTranspose()
{
int[][] trans = new int[columnCount()][rowCount()];
for (int i = 0; i < rowCount(); i++)
for (int j = 0; j < columnCount(); j++)
trans[i][j] = getValue(j, i);
return new Matrix(trans);
}
#Override
public String toString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < numbers.length; i++)
{
for (int j = 0; j < numbers[i].length; j++)
sb.append(' ').append(numbers[i][j]);
sb.append('\n');
}
return sb.toString();
}
public static void main(String[] args)
{
final int[][] m1 = new int[][] { { 1, 4 }, { 5, 3 } };
Matrix mat = new Matrix(m1);
System.out.print(mat);
System.out.print(mat.getTranspose());
}
}
for a quick and dirty method:
public String toString() {
return Arrays.deepToString(numbers);
}
On an unrelated note, the variables rows, colms, numbers and the methods isSquareMatrix should not be declared as static. Otherwise, when you get a transpose, you're going to end up with two matrix objects writing to the same class variables.
You didn't define a toString method for your Matrix class, so when you try to print a Matrix you see the result of the default toString method which prints the object's class and unique id.
System.out.print(Mat);
it will call the toString method of the Matrix class.
So, if you want to print your Matrix, you will have to override toString method
#Override
public String toString() {
// create here a String representation of your matrix
// ie: String myString = "1 0 0 1\n0 1 1 1\n...";
return "String representation of my matrix";
}
To display the Matrix class object when you can print on it you'll have to define the toString method in your class.
Another bug in the code it you are not setting the value of rows and colms. So when you do
numbers = new int[rows][colms];
in your constructor, rows and colms will always have their default value of 0. You need to fix that. And then you'll have to copy the matrix elements from the parameter array to numbers.

Categories