Method Scope of variables (java) - java

I have a class in java for methods. Basically this class receives an array of integer numbers, adds the numbers & subtracts them too, returns the sum and the subtraction. I declared the variables at the top (not in a particular method). When the subtraction and the addition are done they're assigned to their respective variables (automatically, of course), BUT when the method is finished doing its job the values are deleted, so when I call a method of the subtraction/addition the result is a 0.
As far as I know the values shouldn't be empty because they're not initialized inside a method but outside all methods, so the scope shouldn't have ended. Any help, please ?
//Class of the methods
package chap3;
import javax.swing.JOptionPane;
/**
*
* #author jtech
*/
public class SimpleArithmeticMethods
{
int sum;
int subtraction;
public void sum_Difference(int[] nums)
{
int[] inpNums = nums;
sum = inpNums[0] + inpNums[1];
subtraction = inpNums[1] - inpNums[0];
}
public void getSum()
{
JOptionPane.showMessageDialog(null,"The sum is: "+sum, "Result.", JOptionPane.INFORMATION_MESSAGE);
}
public void getDifference()
{
JOptionPane.showMessageDialog(null,"The difference is: "+subtraction, "Result.", JOptionPane.INFORMATION_MESSAGE);
}
}
The class from which I run
package chap3;
import javax.swing.JOptionPane;
/**
*
* #author jtech
*/
public class SimpleArithmetic
{
public static void main(String[] args)
{
String[] strInptNums = new String[2];
int[] inptNums = new int[2];
SimpleArithmeticMethods obtainSum = new SimpleArithmeticMethods();
SimpleArithmeticMethods obtainDifference = new SimpleArithmeticMethods();
SimpleArithmeticMethods workSum_Difference = new SimpleArithmeticMethods();
for (int counter = 0; counter <= 1; counter++)
{
strInptNums[counter] = JOptionPane.showInputDialog(null, "Input a number, smallest first", "Input Data.", JOptionPane.QUESTION_MESSAGE);
inptNums[counter] = Integer.parseInt(strInptNums[counter]);
}
workSum_Difference.sum_Difference(inptNums);
obtainSum.getDifference();
obtainDifference.getDifference();
}
}

You're calling the sum_Difference() method on one object, and display the results using another object.
That's like storing a message in a bottle, and then looking if the message is in another bottle. Use the same object to call all three methods.

Related

How to import Java file method to another Java file?

I have two Java files, one called Assign_2 and another called ArrayMath. I want to allow ArrayMath's methods to be used in Assign_2 like so:
ArrayMath.arrayAddition(a, b); //Called ArrayMath from Assign_2.java
What code allows ArrayMath.java methods to be used in Assign_2.java?
public class Assign_2 {
/**
* Main method to execute whole code.
*
* #param theArgs is used to keep consistency
*/
public static void main(String[] theArgs) {
Scanner input = null; // For file input
PrintStream output = null; // For file output
String inFileName = "in2a.txt"; //Input file and outputs
String outFileName = "out.txt";
boolean filesOk = false; // Checks for files to be accessed
int[][] a = null; // Declaring the 4 arrays for operations
int[][] b = null;
int[][] c = null;
int[][] d = null;
// Opens file for input and readys for output
try {
input = new Scanner(new File(inFileName));
output = new PrintStream(new File(outFileName));
filesOk = true;
}
catch (FileNotFoundException e) {
System.out.println("Can't open file - " + e);
}
if (filesOk) {
a = get2DArray(input);
b = get2DArray(input);
c = get2DArray(input);
d = get2DArray(input);
// Sanity check for what is in the array and if right
//System.out.println(Arrays.deepToString(a));
//System.out.println(Arrays.deepToString(b));
//System.out.println(Arrays.deepToString(c));
//System.out.println(Arrays.deepToString(d));
// Calling to ArrayMath.java for operation results
// Declaring arrays for final results
int[][] sum = ArrayMath.arrayAddition(a, b);
System.out.println(Arrays.deepToString(sum));
//int[][] difference = ArrayMath.arraySubtraction(a, b);
//int[][] multiplication = ArrayMath.arrayMultiply(a, b);
}
}
/**
* get2DArray reads input file then creates 2D array
* from the file.
*
* #param input is a Scanner to input the file
*
* #return a 2D integer array filled with input values
*/
public static int[][] get2DArray(Scanner theIn) {
int rowSize = theIn.nextInt(); // Takes the first 2 numbers
int colSize = theIn.nextInt(); // that provided column + row #'s
int[][] a = new int[rowSize][colSize]; // New array with ^ #'s
// For loops that add integers to arrays
for (int i = 0; i < a.length; i++) {
for (int k = 0; k < a[i].length && theIn.hasNextInt(); k++) {
a[i][k] = theIn.nextInt();
}
}
return a; // Returns value to main method that was called from
}
}
And ArrayMath.java is:
public class ArrayMath {
/**
* Addition for 2D Arrays method
*
* #param theA and theB are 2D arrays from Assign_2
*
* #return sum to Assign_2 main program
*/
public static int[][] arrayAddition(int[][] theA, int[][] theB) {
int[][] sum = new int[theA.length][theA.length];
for (int i = 0; i < theA.length; i++) {
for (int k = 0; k < theA[i].length; k++) {
sum[i][k] = theA[i][k] + theB[i][k];
}
}
return sum;
}
}
What you need is to define the method(s) in ArrayMath as public and static, e.g.:
public static void arrayAddition(int a, int b)
{
// do something
}
Define the method in you want to import ArrayMath.java as static.
Assume the wrapper class is just called ArrayMath, make it a public method and then from Assign_2 do import ArrayMath.
refer to the method like ArrayMath.yourMethod().
Call the method after you create an object for ArrayMath class:
ArrayMath ob = new ArrayMath();
Then call the method in Assign_2 class asfollowing
ob.arrayAddition(a, b);
Make sure the method is public.
What all you have to do is to create an object from ArrayMath and use the method declared inside Assign_2
E.g:
ArrayMath obj = new ArrayMath();
obj.arrayAddition(a, b);
Read more about creating objects in Java
There are multiple ways
1. inheritance is-a relationship
2. composition has-a relationship - but in case of has-a relationship you have to made public and static to your method to call from another class.

Object in ArrayList is changing

I made a test program because I am trying to get back into Java after working in PL/SQL. I created a class Numbers that contains an integer, a getter and a setter. I have another class Test that is creating an instance of Numbers, and also adds that instance to a List. I created a for loop that loops two times and sets the value of the integer in Numbers equal to i. I then add that instance of Numbers to the List numbersList. I then do a print screen of the value that was added to the List. I do a total of 3 prints, one print the first time through the loop that prints the first position in the List, then I print two times during the second time through the loop,the first position in the List again, and the second position in the List. I was expecting to get 0,0,1 as the result. I am getting instead 0,1,1 as the result and I cannot figure out why. I am not changing anything in the first position in the List (numbersList[0]) during the second time through the loop, all I am doing is adding an instance of Numbers into the second position in the list (numbersList[1]).
import java.util.ArrayList;
import java.util.List;
public class Tests {
static int x;
public static void main(String[] args) {
List<Numbers> numbersList = new ArrayList<Numbers>();
Numbers numbers = new Numbers();
Numbers numbers2 = new Numbers();
for (int i = 0; i < 2; i++) {
if (i == 0) {
numbers.setVariable(i);
numbersList.add(numbers);
System.out.println(numbersList.get(0).getVariable());
}
if (i > 0) {
numbers2.setVariable(i);
numbersList.add(numbers2);
System.out.println(numbersList.get(0).getVariable());
System.out.println(numbersList.get(1).getVariable());
}
}
}
}
public class Numbers {
public static int a = 5;
public static void setVariable(int b) {
a = b;
}
public static int getVariable() {
return a;
}
}
public static int a = 5 means that all instances of Numbers share the same variable because of the static keyword.
Therefore, when you do numbers2.setVariable(i);, the variable is also changed for numbers. Hence the 0,1,1
If you want instance variables remove the static keywords from Numbers.
Your class Numbers has no instance fields (everything is static, or class level).
It should look something like (and overriding toString() is a good idea),
public class Numbers {
public int a = 5;
public void setVariable(int b){
a = b;
}
public int getVariable(){
return a;
}
#Override
public String toString() {
return String.valueOf(a);
}
}
By overriding toString() you can more easily print instances of Numbers. For example,
System.out.println(numbersList);

Inheritance and InputBox

So I have a super class called Factorial and two subclasses called Fibonacci and Arithmetic. In my main super class which I call the method using a polymorphic array from my main class, I have an input box inquiry that I want to only show up once, but instead it shows up multiple times. Is there anyway I can stop this? My main class is called PolyMorphism. I know it's tedious but it's the way I made the program and want it to be :p
public class Polymorphism {
public static void main(String[] args) {
Factorial arrayObject[] = new Factorial[3];
arrayObject[0] = new Factorial();
arrayObject[1] = new Fibonacci();
arrayObject[2] = new Arithmetic();
for(int x=0;x<arrayObject.length;++x){
arrayObject[x].sequence();
}
public class Factorial extends JFrame {
//this input box shows up 3 times when I launch.
public final String valueInput = JOptionPane.showInputDialog("Please enter a number between 1 and 20.");
public void sequence(){
System.out.println("Factorial:");
System.out.println(fact(Integer.valueOf(valueInput)));
public static long fact (int n){
if (n <= 1){
return 1;
}else
return n * fact(n-1);
}
public class Fibonacci extends Factorial {
public void sequence(){
int inputValue = Integer.parseInt(valueInput);
System.out.println("Fibonacci Sequence");
/**for (int value = 0; value < inputValue; value++){
System.out.println(fibonacciSequence(value));
} **/
System.out.println(fibonacciSequence(inputValue));
}
public static long fibonacciSequence(int v) {
// TODO Auto-generated method stub
if(v == 0) {
return 0;
}else if (v <= 2){
return 1;
}
long fibonacci = fibonacciSequence(v - 1) + fibonacciSequence(v-2);
return fibonacci;
}
}
The comment with the problem is under the Factorial class, and disregard the JFrame for now.
In your Factorial class, you have this:
public final String valueInput = JOptionPane.showInputDialog("Please enter a number between 1 and 20.");
Which means every time you create an instance of it or a subclass, that input dialog will pop up.
The answer is: Don't do that.
Put it in a method and call the method when you want the input dialog to show.
Each Factorial instance (of which you have three) has its own valueInput property, so the behavior is as expected. You could make this field static (and therefore shared), but it's still not clear what you're trying to accomplish.
It's most likely the case that you should be separating the input display from the Factorial implementation entirely.

Constructor undefined

I have a problem with my code, in that it keeps saying that the constructor is undefined. I already read somewhere that I need to declare the constructor with no arguments. I just don't know how to do that.
If someone could help, I am new at java and programming. My code is below:
import java.util.*;//import library
class Input
{
public Input (int size,int startV,int endingV)
{
//declarations of variables
double difference;
double[] array= new double[size];
array[0]=startV;
//calculating the difference to add on each number in the array
difference=(endingV-startV)/size;
for (int counter=1;counter<size;counter++) //for loop to fill the array
{
array[counter]=array[counter-1] + difference;
}
}
public Input enter(int size,int startV,int endingV)
{
//declarations of variables
double difference;
double[] array= new double[size];
array[0]=startV;
//calculating the difference to add on each number in the array
difference=(endingV-startV)/size;
for (int counter=1;counter<size;counter++) //for loop to fill the array
{
array[counter]=array[counter-1] + difference;
}
return this;
}
}
class Show
{
public Show (int size,double[] array)
{
for (int i=0;i<size;i++) //for loop to print the array
System.out.println("This is the array " + i+ ": " + array[i]);
}
public Show print(int size,double[] array)
{
for (int i=0;i<size;i++) //for loop to print the array
System.out.println("This is the array " + i+ ": " + array[i]);
return this;
}
}
public class Assignment2
{
public static void main(String[] args)
{
//declaring variables
int startV,endingV;
int size=0;
System.out.print("Give the size of the array:");//Print message on screen
size = new Scanner(System.in).nextInt();//asking for the size of array
double[] array= new double[size]; //creation of array
System.out.print("Give the starting value of the array:");
startV = new Scanner(System.in).nextInt();//asking for the starting value of array
System.out.print("Give the ending value of the array:");
endingV = new Scanner(System.in).nextInt();//asking for the last value of array
//calling the functions from the other classes
Input enter= new Input(size,startV,endingV);
Show print= new Show(size,array);
}
}
You're close:
You have a method:
public Method enter(int size,int startV,int endingV) {
to make it a constructor it's signature must be
public Method (int size,int startV,int endingV) {
and you then have to delete the return this; statement.
Remember, constructors don't have a return type and their name is identical to the name of the class. With this information, you'll also be able to fix the Method1 constructor.
Also, please respect the Java naming conventions and have variables start with a lower-case letter to improve the readability of your code.
You need to create a
public Method(size,startV,endingV)
not
public Method enter = (size, startV, endingV)
The first is a constructor the second is a method
For class Method
the default constructor will be
public Method(){}
For class Method1
the default constructor will be
public Method1(){}
in your classes there are no constructors as the
constructor name must be will the same as class name.
enter(int size,int startV,int endingV)
and
print(int size,double[] array)
can be two methods in your classes.
also your two constructor can be -
public Method(int size,int startV,int endingV){ /..../}
and
public Method1(int size,double[] array){ /..../}
Your constructor must have the same name than your class and has no return type. So for your class Method, your constructor will simply be :
public Method(int size, int startV, int endingV)
{
// code...
}
Please also note that constructors exist to initialize your instances of objects, if you want to create a method that does a specific calcul, then yes, you'll have to do :
public int enter(int size, int startV, int endingV)
{
int result = 0;
// code to calculate, for example result = size + startV + endingV ...
return result;
}

What to do when you need to store a (very) large number?

I am trying to do a Project Euler problem but it involves adding the digits of a very large number. (100!)
Using Java int and long are too small.
Thanks for any suggestions
Class BigInteger
looks like it might be what you are looking for.
Use BigInteger. Here is an example from the book Java Examples in a Nutshell that involves computing factorials, with caching.
import java.math.BigInteger;
import java.util.ArrayList;
/*
* Copyright (c) 2000 David Flanagan. All rights reserved.
* This code is from the book Java Examples in a Nutshell, 2nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or
* implied. You may study, use, and modify it for any non-commercial
* purpose. You may distribute it non-commercially as long as you
* retain this notice. For a commercial use license, or to purchase
* the book (recommended), visit
* http://www.davidflanagan.com/javaexamples2.
*/
/**
* This program computes and displays the factorial of a number
* specified on the command line. It handles possible user input
* errors with try/catch.
*/
public class FactComputer {
public static void main(String[] args) {
// Try to compute a factorial.
// If something goes wrong, handle it in the catch clause below.
try {
int x = Integer.parseInt(args[0]);
System.out.println(x + "! = " + Factorial4.factorial(x));
}
// The user forgot to specify an argument.
// Thrown if args[0] is undefined.
catch (ArrayIndexOutOfBoundsException e) {
System.out.println("You must specify an argument");
System.out.println("Usage: java FactComputer <number>");
}
// The argument is not a number. Thrown by Integer.parseInt().
catch (NumberFormatException e) {
System.out.println("The argument you specify must be an integer");
}
// The argument is < 0. Thrown by Factorial4.factorial()
catch (IllegalArgumentException e) {
// Display the message sent by the factorial() method:
System.out.println("Bad argument: " + e.getMessage());
}
}
}
/**
* This version of the program uses arbitrary precision integers, so it
* does not have an upper-bound on the values it can compute. It uses an
* ArrayList object to cache computed values instead of a fixed-size
* array. An ArrayList is like an array, but can grow to any size. The
* factorial() method is declared "synchronized" so that it can be safely
* used in multi-threaded programs. Look up java.math.BigInteger and
* java.util.ArrayList while studying this class.
* Prior to Java 1.2, use Vector instead of ArrayList
*/
class Factorial4 {
protected static ArrayList table = new ArrayList(); // create cache
static { // Initialize the first element of the cache with !0 = 1.
table.add(BigInteger.valueOf(1));
}
/** The factorial() method, using BigIntegers cached in a ArrayList */
public static synchronized BigInteger factorial(int x) {
if (x < 0)
throw new IllegalArgumentException("x must be non-negative.");
for (int size = table.size(); size <= x; size++) {
BigInteger lastfact = (BigInteger) table.get(size - 1);
BigInteger nextfact = lastfact.multiply(BigInteger.valueOf(size));
table.add(nextfact);
}
return (BigInteger) table.get(x);
}
/**
* A simple main() method that we can use as a standalone test
* program for our factorial() method.
*/
public static void main(String[] args) {
for (int i = 0; i <= 50; i++)
System.out.println(i + "! = " + factorial(i));
}
}
java.lang.BigInteger or java.lang.BigDecimal
import java.math.BigInteger;
import java.util.*;
public class Main {
protected static ArrayList<BigInteger> table = new ArrayList<BigInteger>();
static {
table.add(BigInteger.valueOf(1));
}
public static synchronized BigInteger factorial(int x) {
if (x < 0) throw new IllegalArgumentException("x must be non-negative.");
for (int size = table.size(); size <= x; size++) {
BigInteger lastfact = table.get(size - 1);
BigInteger nextfact = lastfact.multiply(BigInteger.valueOf(size));
table.add(nextfact);
}
return table.get(x);
}
public static void main(String[] args) {
for (int i = 0; i <= 50; i++)
System.out.println(i + "! = " + factorial(i));
}
}

Categories