How to call an Array between classes? - java

Hello I am new to java so please be gentle,
class Result{
public float Mean(){
//find the mean of the array
}
public float lowest(){
// find the lowest
}
}
public class Main{
public static void main(String[] args) {
float arr[] = {1.1,2.2,3.3};
}
}
What I want to do is to take the array arr from Main, and bring it to class Result so that I can use it
in Mean() and Lowest().
Thank you.

Try add the array as part of constructor of Result/Solve, then you could work with numbers inside the instance you create.
class Solve {
final float[] numbers;
public Result(final float[] numbers){
this.numbers = numbers;
}
public float mean(){
//find the mean using the this.numbers
}
public float lowest(){
// find the lowest using this.numbers
}
}
public class Main{
public static void main(String[] args) {
float numbers[] = new float[]{1.1,2.2,3.3};
Solve solve = new Solve(numbers);
float mean = solve.mean();
float lowest = solve.lowest();
System.out.println("Mean: " + mean);
System.out.println("Lowest: " + lowest);
}
}
Another option is to make your methods static and pass the numbers as part of the methods, similar to Math class.
class Solve {
public static float mean(float[] numbers){
}
public static float lowest(float[] numbers) {
}
}
public class Main{
public static void main(String[] args) {
float numbers[] = new float[]{1.1,2.2,3.3};
float mean = Solve.mean(numbers);
float lowest = Solve.lowest(numbers);
System.out.println("Mean: " + mean);
System.out.println("Lowest: " + lowest);
}
}

Here's how I would handle this:
Result class:
class Result {
public static float mean(float... arr) { //make the method static, and have it take the array as a parameter
float sum = 0f;
for (float f : arr) { //add each number in the array to the sum variable
sum += f;
}
return sum / arr.length; //return sum / length, which is average
}
public static float lowest(float... arr) { //same as the above method
float lowest = arr[0];
for (float f : arr) { //loop through the array
if (f < lowest) { //if this number is lower than the current "lowest" number, set lowest to be this number
lowest = f;
}
}
return lowest; //return the lowest number
}
}
Main class:
public class Main {
public static void main(String[] args) {
float[] arr = new float[] { 1.1f, 2.2f, 3.3f }; //here's the array
System.out.println(Result.mean(arr)); //I pass it to the method as a parameter
System.out.println(Result.lowest(arr)); //same here
}
}
An alternative solution would be to use Java streams instead of for loops. Java streams can get more complicated than for loops, but they can be much cleaner and easier to read. Here's how I would rewrite the Result class using streams:
class Result {
public static float mean(float... arr) {
return (float) IntStream.range(0, arr.length)
.mapToDouble((i) -> arr[i])
.average()
.getAsDouble(); //returns the average of the array
}
public static float lowest(float... arr) {
return (float) IntStream.range(0, arr.length)
.mapToDouble((i) -> arr[i])
.min()
.getAsDouble(); //returns the minimum value in the array
}
}

Pass your array as an argument to the other object’s method.
float[] arr = { 1.1F, 2.2F, 3.3F } ;
Result r = new Result() ;
float output = r.lowest( arr ) ;
Define that argument on the method.
class Result{
public float mean( float[] input ){
// … find the mean of the array
}
public float lowest( float[] input ){
// … find the lowest
}
}
See this code run live at IdeOne.com.
Passing an argument/parameter to a method is a basic minimal skill in Java. You should study the Java Tutorials by Oracle, and consult a textbook to get the basics down.

Related

How to fix this VarArgs build error?

Here's the main method:
package main;
import varArgs.VarArgs;
public class Main {
public static void main(String[] args) {
int answer;
answer = VarArgs.sum(new int[]{1,2,3});
System.out.println("sum of ints = " + answer);
answer = VarArgs.sum(new int[]{1,2,3}, new int[] {100, 200, 300});
System.out.println("sum of ints = " + answer);
}
}
Here's the var args method:
package varArgs;
public class VarArgs {
/***
* Add an array of integers
* #param numbers Some array of integers
* #return The sum of all the elements in num
*/
public static int sum(int... numbers) {
int result = 0;
for (int i : numbers) {
result += i;
}
return result;
}
}
Here's the error I get:
A varargs parameter can only accept a single array. If you want to pass in a variable number of arrays, you need to do this:
public static int sum(int[]... arrays) {
int sum = 0;
for (int[] numbers : arrays) {
for (int i : numbers) {
sum += i;
}
}
return sum;
}

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;
}

Median Absolute Deviation in Java

How to calculate the Median Absolute Deviation (MAD) in Java from a list (e.g. List<Double> list)?
I found some implementations on stackoverflow in programming languages I don't know (e.g. in C# and in R) but none of them is in Java.
To calculate median:
You can use Arrays.sort() to sort the input array, then if arrayLength%2==0 then median value is (array[array.length/2-1] + array[array.length/2])/2 otherwise the median is (array[array.length/2]).
To calculate MAD:
Create Double[] intermediate - new Double[array.length] and calculate the intermediate array using intermediate[i] = Math.abs(input[i]-median) for each element, then calculate the median for the intermediate array same way as in the first step and you're ready.
Example I've made for you:
import java.util.Arrays;
import java.util.List;
public class MAD {
public static void main(String[] args) {
List<Double> input = Arrays.asList(new Double[] {1d, 1d, 2d, 2d, 4d, 6d, 9d});
System.out.println(mad(input));
}
private static Double mad(List<Double> inputList) {
Double[] input = inputList.toArray(new Double[inputList.size()]);
Double median = median(input);
arrayAbsDistance(input, median);
return median(input);
}
private static void arrayAbsDistance(Double[] array, Double value) {
for (int i=0; i<array.length;i++) {
array[i] = Math.abs(array[i] - value);
}
}
private static Double median(Double[] input) {
if (input.length==0) {
throw new IllegalArgumentException("to calculate median we need at least 1 element");
}
Arrays.sort(input);
if (input.length%2==0) {
return (input[input.length/2-1] + input[input.length/2])/2;
}
return input[input.length/2];
}
}

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();
}
}

Random value from enum with probability

I have an enum that I would like to randomly select a value from, but not truly random. I would like some of the values to be less likely of being selected so far. Here is what I have so far...
private enum Type{
TYPE_A, TYPE_B, TYPE_C, TYPE_D, TYPE_E;
private static final List<Type> VALUES =
Collections.unmodifiableList(Arrays.asList(values()));
private static final int SIZE = VALUES.size();
private static final Random RANDOM = new Random();
public static Type randomType() {
return VALUES.get(RANDOM.nextInt(SIZE));
}
}
Is there an efficient way of assigning probabilities to each of these values?
Code found from here
several ways to do it, one of them, similar to your approach
private enum Type{
TYPE_A(10 /*10 - weight of this type*/),
TYPE_B(1),
TYPE_C(5),
TYPE_D(20),
TYPE_E(7);
private int weight;
private Type(int weight) {
this.weight = weight;
}
private int getWeight() {
return weight;
}
private static final List<Type> VALUES =
Collections.unmodifiableList(Arrays.asList(values()));
private int summWeigts() {
int summ = 0;
for(Type value: VALUES)
summ += value.getWeight();
return summ;
}
private static final int SIZE = summWeigts();
private static final Random RANDOM = new Random();
public static Type randomType() {
int randomNum = RANDOM.nextInt(SIZE);
int currentWeightSumm = 0;
for(Type currentValue: VALUES) {
if (randomNum > currentWeightSumm &&
randomNum <= (currentWeightSumm + currentValue.getWeight()) {
break;
}
currentWeightSumm += currentValue.getWeight();
}
return currentValue.get();
}
}
Here's a generic approach to choosing an enum value at random. You can adjust the probabilities as suggested here.
Assuming you have a finite number of values you could have a separate array (float[] weights;) of weights for each value. These values would be between 0 and 1. When you select a random value also generate another random number between and only select the value if the second generated number is below the weight for that value.
You can create an enum with associated data bby provding a custom constructor, and use the constructor to assign weightings for the probabilities and then
public enum WeightedEnum {
ONE(1), TWO(2), THREE(3);
private WeightedEnum(int weight) {
this.weight = weight;
}
public int getWeight() {
return this.weight;
}
private final int weight;
public static WeightedEnum randomType() {
// select one based on random value and relative weight
}
}
import java.util.*;
enum R {
a(.1),b(.2),c(.3),d(.4);
R(final double p) {
this.p=p;
}
private static void init() {
sums=new double[values().length+1];
sums[0]=0;
for(int i=0;i<values().length;i++)
sums[i+1]=values()[i].p+sums[i];
once=true;
}
static R random() {
if (!once) init();
final double x=Math.random();
for(int i=0;i<values().length;i++)
if (sums[i]<=x&&x<sums[i+1]) return values()[i];
throw new RuntimeException("should not happen!");
}
static boolean check() {
double sum=0;
for(R r:R.values())
sum+=r.p;
return(Math.abs(sum-1)<epsilon);
}
final double p;
static final double epsilon=.000001;
static double[] sums;
static boolean once=false;
}
public class Main{
public static void main(String[] args) {
if (!R.check()) throw new RuntimeException("values should sum to one!");
final Map<R,Integer> bins=new EnumMap<R,Integer>(R.class);
for(R r:R.values())
bins.put(r,0);
final int n=1000000;
for(int i=0;i<n;i++) {
final R r=R.random();
bins.put(r,bins.get(r)+1);
}
for(R r:R.values())
System.out.println(r+" "+r.p+" "+bins.get(r)/(double)n);
}
}
Here is another alternative which allows the distribution to be specified at runtime.
Includes suggestion from Alexey Sviridov. Also method random() could incorporate suggestion from Ted Dunning when there are many options.
private enum Option {
OPTION_1, OPTION_2, OPTION_3, OPTION_4;
static private final Integer OPTION_COUNT = EnumSet.allOf(Option.class).size();
static private final EnumMap<Option, Integer> buckets = new EnumMap<Option, Integer>(Option.class);
static private final Random random = new Random();
static private Integer total = 0;
static void setDistribution(Short[] distribution) {
if (distribution.length < OPTION_COUNT) {
throw new ArrayIndexOutOfBoundsException("distribution too short");
}
total = 0;
Short dist;
for (Option option : EnumSet.allOf(Option.class)) {
dist = distribution[option.ordinal()];
total += (dist < 0) ? 0 : dist;
buckets.put(option, total);
}
}
static Option random() {
Integer rnd = random.nextInt(total);
for (Option option : EnumSet.allOf(Option.class)) {
if (buckets.get(option) > rnd) {
return option;
}
}
throw new IndexOutOfBoundsException();
}
}
You can use EnumeratedDistribution from the Apache Commons Math library.
EnumeratedDistribution<Type> distribution = new EnumeratedDistribution<>(
RandomGeneratorFactory.createRandomGenerator(new Random()),
List.of(
new Pair<>(Type.TYPE_A, 0.2), // get TYPE_A with probability 0.2
new Pair<>(Type.TYPE_B, 0.5), // get TYPE_B with probability 0.5
new Pair<>(Type.TYPE_C, 0.3) // get TYPE_C with probability 0.3
)
);
Type mySample = distribution.sample();

Categories