Pass values from a constructor to a method - java

I have to pass the values that are in my Guitar constructor and then pass them to the generateSong method. There is one catch. The generate song method can not take parameters in because since the values are in the same class, they should be able to be able to take in the values from the constructor.
When I try to implement the values in that method, the values are not able to be accessed. How can I fix this?
public Guitar(int chord, int numOfStrings) {
//pass these values to the generateSong method
System.out.println("Guitar () generated a guitar with: " + numOfStrings + "." + "Song length is " +chord);
// declare the array for which the song is stored
// store the values of the last row i (highest index of the array)
double[] max = null;
Guitar.generateSong();
// start the generate song method
public static void generateSong () {
double [] [] song = new double [numOfStrings] [chord];
double[] max;
int findmax =0;
int sum =0;
for (int i =0; i<song.length; i++) {
for (int j =0; j<song.length; j++ ) {
sum = (int) (sum +song[i][j]);
}
for (int e=0; e<song.length; e++) {
if (song[e]!=song[findmax] ) {
max[e] =e;
}
for(int k=0; k<song.length; k++) {
for (int l=0; k<song[k].length; k++)
// assign note values to the array
song [k] [l] = 27.5 + (Math.random()* 4186);
// print out the proper value
System.out.printf("8.2%f", song);
for( int m=0; m<max.length; m++)
max[m]= 1 +( Math.random() *3);
System.out.printf("8.2%f", max);
}
}
}
}
The values int chord and int numOfStrings come from command line parameters in the main method and are passed to this method through the following object:
Guitar guitar = new Guitar (numOfStrings, chord);

So, there are two syntax errors and one misunderstanding of the requirement. Let's start with the misunderstanding.
The generate song method can not take parameters in because since the values are in the same class, they should be able to be able to take in the values from the constructor.
This is only accomplishable via fields. You need to set your constructor up so that fields for those values are created, which can then be used everywhere else in this class.
In this scenario...
public class Guitar {
private int chord;
private int numberOfStrings;
public Guitar(final int chord, final int numberOfStrings) {
this.chord = chord;
this.numberOfStrings = numberOfStrings;
}
}
Second, you can't define methods inside of other methods. Move the definition of your generateSong method out of the constructor.
Third, don't make the generateSong method static! You create an instance of these to use, and you use that instance inside of main to perform the behavior you want.
// in main()
Guitar guitar = new Guitar(4, 10);
guitar.generateSong();
As an addendum, you need to be sure that you parse the integers you get from the command line, as those values are always going to be coming in as String. I leave this as an exercise for the reader.

Related

how to reassign array variable stored in an object in java

I'm new to this site so let me know if this sort of question is welcome here.
I'm currently coding a class in java to store a set of integers in an array stored in an object and i'm having trouble reassigning the array variable store in the objects created. its not compiling as is(I'm a new programmer so i'm pretty sure i'm missing something simple here).
public class Set
{
// constructor
Set()
{
int array[] = {};
}
//adds a value to the set
public static void addValue(int [] array, int element)
{
int i;
int n = array.length;
int newArray[] = new int[n + 1];
//copy original array into new array
for (i = 0; i < n; i++)
newArray[i] = array[i];
//add element to the new array
newArray[n] = element;
//the issue is this line here
this.array = newArray;
}
//print the set
public static void printSet(int [] array)
{
int i;
int n = array.length;
System.out.print("{");
for (i = 0; i < n; i++)
{
System.out.print(array[i]);
}
System.out.println("}");
}
}
edit - error message returned is:
Set.java:23: error: non-static variable this cannot be referenced from a static context
this.array = newArray;
^
Set.java:23: error: cannot find symbol
this.array = newArray;
^
symbol: variable array
2 errors
First of all, you forgot to put the array inside the class, you can handle it privately like this before the constructor in this way:
private int [] array;
Constructor is used to initialize objects. If you create an empty constructor, you won't be able to pass it any parameters to initialize the array. You can create the constructor this way:
Set (int [] array){
this.array = array;
}
At line you indicated the compiler tells you that you cannot handle the method statically because you are working on an instance method. The "this" keyword is used as a reference to an instance. Since the static methods doesn't have (belong to) any instance you cannot use the "this" reference within a static method. So, you have to remove the static handling from the method. Also, since you want to return the array with the entered value, your method cannot be of type void. So, your method will be:
//adds a value to the set
public int [] addValue(int [] array, int element){
int newArray[] = new int[array.length + 1];
for (int i = 0; i < array.length; i++)
newArray[i] = array[i];
newArray[array.length] = element;
return newArray;
}
Since the length of the array was already available (array.length), it was not necessary to create the variable n, so I took the liberty of making some improvements to your code, to make it less redundant. Similarly, the method you created to print the array would be:
//print the set
public void printSet(int [] array){
System.out.print("{ ");
for (int i = 0; i < array.length; i++){
System.out.print(array[i] + " ");
}
System.out.println("} ");
}
However, once you've made these small changes your code should work fine. You can try to create a testing class like this, to check that everything works right:
public class TestingSet {
public static void main (String [] args){
//creating array
int [] array = {1, 2, 3};
//creating an instance of Set class
Set s = new Set(array);
//printing array
s.printSet(array);
//printing array with new value
s.printSet(s.addValue(array,4));
}
}
It looks like you are trying to access array however it cannot be seen by the addValue method.
You need to declare the array outside of the Set constructor:
public class Set
{
//New location to declear the array
int array[];
// constructor
Set()
{
//We can still initialize the array here
array[] = {};
}
Secondly, the reason for the error is that you cannot use this inside a static method. Static methods are not tied to an object (The Set class) so you need removed static from the method:
//static removed from this line
public void addValue(int [] array, int element)
{
Then to use the method you would create the Set object and use addValue something like this:
Set exampleSet = new Set();
exampleSet.addValue(yourArray, index);
The other option is to make the array a static value (it will no longer be specific to the object but shared with everything), but this is proberbly not the behaviour you want:
public class Set
{
//New location to declear the array
static int array[];
//And to access the object you could use
Set.array = newArray;

Returning a 2-Dimensional Array from a method

I'm trying to return a 2-dimensional array from a function inside of a class. I don't want to create a new array inside the function because I want to return the same one I've passed into the function.
I've tried creating a new array with the same name, but it says it's already defined within the scope. I've also tried just doing (return plane;) which doesnt work because of incompatible data types. I've also tried (return plane[][];) but that doesnt work either.
public class Airplane {
private String maxSeats; //used for constructor
private char[][] plane = new char[13][6]; //array to be passed in
public char create(char[][] plane) {
plane[13][6]; //this is where I'm unsure what to do
//initialize them as '*' to start
for (int i = 0; i <= 12; i++) {
for ( int k = 0; k <= 5; k++) {
plane[i][k] = '*';
}
return plane;
}
}
I'm trying to return the array to be used in another function where I will modify it.
You have to change the return type to char[][] since you want to return a 2-dimensional array of characters and not just a single character
public class Airplane {
private String maxSeats;
private char[][] plane = new char[13][6];
public char[][] create(char[][] plane) {
// plane[13][6]; you should remove this line, it's the wrong syntax
//and it's unneeded since you've already declared this array
// this is a more compact version of your nested loop
for (int i = 0; i < 13; i++) {
Arrays.fill(plane[i], '*'); //fills the whole array with the same value
}
return plane;
}
}

Implementing object parameters in other classes

I'm hoping someone can help me with these two values that have me stuck on a project. I have two classes and this first one generates a 2D array with random values.
import java.util.concurrent.ThreadLocalRandom;
public class Guitar {
private int strings;
private int chords;
public Guitar(int mstrings, int mchords) {
this.strings = mstrings;
this.chords = mchords;
}
private double[][] song = new double[strings][chords];
public void generateSong() {
for (int i = 0; i < song.length; i++) {
for (int j = 0; j < song[i].length; j++) {
song[i][j] = ThreadLocalRandom.current().nextDouble(27.5, 4186);
System.out.printf(" %.2f",song[i][j]);
}
System.out.println();
}
}
}
The number of rows and columns is determined by command line arguments. args[0] is the number of rows, args[1] is the number of columns. I converted them to int variables in the main method class
public class Songwriter {
public static void main(String[] args) {
System.out.println("Guitar(): Generated new guitar with " + args[0] + " strings. Song length is " + args[1] + " chords.");
String args0 = args[0];
int strings = Integer.parseInt(args0);
String args1 = args[1];
int chords = Integer.parseInt(args1);
Guitar guitarObj1 = new Guitar(strings, chords);
guitarObj1.generateSong();
}
}
My problem lies in passing the int variables of the command line arguments to make the 2D array the corresponding size. I know my code isn't completely wrong b/c when I set the strings and chords variables equal to 3 and 4 or whatever in the Guitar class itself, the table prints fine.
Sorry if I seem clueless. My class just covered the first chapter on object oriented programming and I've yet to get the fundamentals down.
This is the problematic line:
private double[][] song = new double[strings][chords];
When you create a new object of your Guitar class, the song array is initialized with whatever the values of strings and chords are at that time, which would (most probably) be 0.
Change it to this:
private double[][] song;
public Guitar(int mstrings, int mchords) {
this.strings = mstrings;
this.chords = mchords;
song = new double[mstrings][mchords];
}
EDIT : OP you just answered your own question :)
It doesn't crash but the only output is the system.out.print in the
first line of the main. I believe it's because the strings and chords
variables default to 0, making the array 0x0, and I'm failing to
change their values

String and Int arrays not being initialized to right values

So what I'm trying to do here is initialize my strings to an empty string and my ints to 0. The display report is kind of a debugger at the moment, and when I run the program that calls displayReport, it only displays my ints and strings as null. It has to be something in my for loop, but I can't seem to figure out what I am doing wrong.
EDIT: To be clear, I HAVE to use private void initializeString(String[] s) and private void initializeInt(int[] a). And my constructor has these guidelines
public constructor: Initializes arrays holding soft drink name and ID to hold all empty strings (calls intitializeString twice to perform the tasks). Initializes arrays holding starting inventory, final inventory, and the counts of the number of transaction to zero (calls initializeInt three times to perform the tasks).
import java.util.Scanner;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class SoftDrinkInventory {
static final int MAXSIZE = 100; // maximum size of 100
private String[] names; // softdrink names
private String[] ids; // softdrink identifications
private int[] startingInventory; // starting inventory of the softdrinks
private int[] finalInventory; // final inventory of the softdrinks
private int[] transactionCounts; // number of transactions per softdrink
private int trueSize; // total number of softdrinks
/**-----------------------------------------------------------------------
* constructor
*
* Initializes arrays holding soft drink name, ID number to the
* empty string. Initializes starting inventory, final inventory,
* and transaction counts are to zero.
*/
public SoftDrinkInventory() {
initializeString(names);
initializeString(ids);
initializeInt(startingInventory);
initializeInt(finalInventory);
initializeInt(transactionCounts);
}
/**-----------------------------------------------------------------------
* displayReport
*
* Displays a report including soft drink name, ID, starting inventory,
* final inventory, and number of transactions processed.
*/
public void displayReport() {
System.out.printf("%-22s %-16s %-23s %-23s %s %n", "Soft Drink", "ID",
"Starting Inventory", "Final Inventory",
"# transaction");
for(int i = 0; i < 10; i++) {
System.out.printf("%-22s %-16s %-23f %-23f %f %n", names, ids,
startingInventory, finalInventory,
transactionCounts);
}
}
/**-----------------------------------------------------------------------
* initializeInt
*
* Takes an int array parameter and initializes its array values to zero.
* #param a int array
*/
private void initializeInt(int[] a) {
a = new int[MAXSIZE];
for(int i = 0; i < a.length; i++) {
a[i] = 0;
}
}
/**-----------------------------------------------------------------------
* initializeString
*
* Takes a String array parameter and initializes its array values to
* the empty string.
* #param s string array
*/
private void initializeString(String[] s) {
s = new String[MAXSIZE];
for(int i = 0; i < s.length; i++) {
s[i] = "";
}
}
}
Java uses pass by value. This means the references you pass in are being modified, not the originals. The simplest solution is to return the array you want.
names = initialiseString(100);
However, a better approach is to use a List of Objects like
private final List<Item> items = new ArrayList<>();
// to add
items.add(new Item("name", "id", 1234, 10, 1224));
// you can add any size 0 up to 2 billion.
int actualSize = items.size();
class Item {
private String name; // softdrink name
private String id; // softdrink identification
private int startingInventory; // starting inventory of the softdrink
private int finalInventory; // final inventory of the softdrink
private int transactionCount;
}
You can't overwrite a reference, that was passed as an argument to a method, inside that method. When you're doing a = new int[MAXSIZE]; you are creating an array that is visible only to that method. What you need to do is return the created array. You might consider doing something like this:
private int[] initializeInt(int size) {
...
}
...
startingInventory = initializeInt(MAXSIZE);
Because you are initializing the arrays local to those initializing methods. Instead of passing argument to the methods, simply create and initialize a new array within the methods and return those arrays to respective instance variables.
For example change your initializeString(String[]) to public String[] initializeString() and within this method write.:
String[] names = new String[MAXSIZE];
for(int i = 0; i < names.length; i++) { names[i] = "";} return names;
And then call this method within your constructor as follows
names = initializeString();
There are Java functions that take an array as a parameter, put data in the array, and it is available to you.
For example:
BufferedReader.read(char[] cbuf, int off, int len)
However, you must first create the array, and it just fills it. So you must first do this before calling that function:
char[] cbuf = new char[100];
Since your methods are initializing arrays in the same class, you can just do Vishal K said, and not pass the arrays to the methods. In situations where you are calling methods elsewhere, you can pass objects as parameters to methods in other classes as long as you create the object first. The callee can use the passed reference to modify your object.
Of course there are better ways to do this (such as using List of Objects, as suggested by Peter Lawrey), but since this is in the specs you have, you can try this: when you declare your arrays, also allocate memory for them :
private String[] names = new String[MAXSIZE]; // softdrink names
private String[] ids = new String[MAXSIZE]; // softdrink identifications
private int[] startingInventory = new int[MAXSIZE]; // starting inventory of the softdrinks
private int[] finalInventory = new int[MAXSIZE]; // final inventory of the softdrinks
private int[] transactionCounts = new int[MAXSIZE]; // number of transactions per softdrink
Then, in your functions, you can simply assign values to 0 and empty String:
private void initializeInt(int[] a) {
for(int i = 0; i < a.length; i++) {
a[i] = 0;
}
}
and
private void initializeString(String[] s) {
for(int i = 0; i < s.length; i++) {
s[i] = "";
}
}
Please note that you have an error in your displayReport() function too. You are using %f to display int values (%f is used for floats). Instead, change it to %d. Also, in your for loop, you are not actually looping through your arrays. Just use i as an index when iterating. Another thing is that you are displaying only 10 entries, whereas your MAXSIZE, which you use to initialise arrays is 100, so if you want to display all array elements, change 10 to MAXSIZE:
public void displayReport() {
System.out.printf("%-22s %-16s %-23s %-23s %s %n", "Soft Drink", "ID",
"Starting Inventory", "Final Inventory",
"# transaction");
for(int i = 0; i < MAXSIZE; i++) {
//change "%-22s %-16s %-23f %-23f %f %n" to the below
//and names etc. to names[i] etc.
System.out.printf("%-22s %-16s %-23d %-23d %d %n", names[i], ids[i],
startingInventory[i], finalInventory[i],
transactionCounts[i]);
}
}

Calculate the number of students who passed - what should I put in the if statement?

The idea is to add students to an arraylist, work out the number of students who have passed, and return that number.
I think I'm nearly there, as the code works, but it always returns the same value for the amount in the array list - and obviously, that is incorrect.
I have been doing this for hours now, and I can't see what the missing statement within the if statement is to finish it off! I would be soo grateful for this!
import java.util.ArrayList;
class Course
{
private ArrayList<Student> people = new ArrayList<Student>();
//Add a students mark
public void add( Student s )
{
people.add(s);
}
//Return the number of students who passed (mark>= 40)
public int pass()
{
int size = people.size();
int i = 0;
int result = 0;
for (i = 0; i < size; i++)
{
Student s = people.get(i);
if(s.getMark() >= 40);
{
// what's here?
}
return result;
}
}
}
Remove this statement inside pass method
ArrayList people = new ArrayList();
Because of this statement, when pass method is called, your local variable hides instance variable.
You are declaring a duplicate, empty people list in the pass() method. Remove it.
You create an ArrayList with no elements, and then create result of type Object[] from it, which will be of length 0.
ArrayList people = new ArrayList();
Object result[] = people.toArray();
Thus, your for loop will not be executed at all.
You probably want to access the instance variable people, you can do it by
Removing the ArrayList people = new ArrayList(); from the method
using this in creating the array: Object result[] =
this.people.toArray();
Firstly, you specify ArrayList people twice, once, outside of the pass method, and the second inside of the pass method. The pass method default uses the one inside of it, which is empty.
mark is always 0. So this does not work:
if ( mark >= 40)
You should return the result after you've finished the for loop, and you should be increasing result instead of i:
public int pass()
{
int size = people.size();
int result = 0;
for (int i = 0; i < size; i++)
{
Student s = people.get(i);
if(s.getMark() >= 40);
result++;
}
return result;
}

Categories

Resources