Related
I'm writing a program that is based around registering the amount of energy consumption that is being used by appliances within a house. So far, I have created various meter classes such as WaterMeter, GasMeter etc. with empty methods that need to be filed with values, I have also created classes for appliances that have methods that will be used to register the consumption of energy within each appliance. What I am working on now is applying the energy values that are stored within a constructor, putting those values into a timePasses() method that will then return those values to their specific meter's methods so that they can be registered. This is what I have so far:
Appliance class example:
public class ElectricShower extends Shower
{
public int isOn = -1;
public int isOff = 0;
public int incrementTime;
public int x = -1;
private static ElectricMeter instance = new ElectricMeter();
public static ElectricMeter getInstance() { return instance; }
#Override
public int currentState()
{
if (x == 0)
return isOff;
else
{
return isOn;
}
//returns isOn;
}
#Override
public void useTime(int defaultTime)
{
defaultTime = 15;
incrementTime = 1;
}
public void shower()
{
//call timePasses() method
}
#Override
public int timePasses()
{
if(x == isOff)
return 0;
else
{
ElectricMeter.getInstance().incrementConsumed(electricityUse);
}
}
ElectricShower(int electricityUse, int gasUse, int waterUse, int timeOn)
{
super(electricityUse, gasUse, waterUse, timeOn);
this.electricityUse = 12 * incrementTime;
this.gasUse = 0 * incrementTime;
this.waterUse = 4 * incrementTime;
this.timeOn = 15 * incrementTime;
}
}
Meter example:
public class ElectricMeter
{
public int incrementConsumed(int value)
{
}
public int incrementGenerated()
{
}
public boolean canGenerate()
{
}
public String getConsumed()
{
}
public String getGenerated()
{
}
}
What I need to do next is:
take the values of electricityUse and waterUse and store them within the timePasses() else staement
Within the timePasses() else statement, place the value of electrcityUse in the incrementGenerated() method within the ElectricMeter class and do the same for the waterUse variable.
UPDATE
Classes have been updated, still struggling to find out how to make it work.
First of all, I assume you have an Appliance class that all the appliances extends from. You should create variables in the Appliance class that stores electricity, gas and water usage:
public class Appliance
{
public int electricityUse, gasUse, waterUse, timeOn;
// ...
}
Note that you should always use getters and setters instead of public fields. I'm just lazy :D
Change your constructor so that the variables above get set:
ElectricShower(int electricityUse, int gasUse, int waterUse, int timeOn)
{
super(electricityUse, gasUse, waterUse, timeOn);
// I don't know why you multiply the constant by incrementTime here. Seems weird. I think you can remove them.
this.electricityUse = 12 * incrementTime;
this.gasUse = 0 * incrementTime;
this.waterUse = 4 * incrementTime;
this.timeOn = 15 * incrementTime;
}
One way to write the else clause is to use the "Singleton Pattern".
In every meter class, write something like this:
private ElectricMeter() {}
private static ElectricMeter instance = new ElectricMeter();
public static ElectricMeter getInstance() { return instance; }
In the incrementConsumed method, you should accept a parameter that indicates how much to increment:
public int incrementConsumed(int value)
{
// logic here...
}
In the else clause, you can just do:
ElectricMeter.getInstance().incrementConsumed(electricityUse);
GasMeter.getInstance().incrementConsumed(gasUse);
WaterMeter.getInstance().incrementConsumed(waterUse);
You should review your design.
If you need to access to a class parameter you could just define it public or better create a so called getter method that returns the value.
Example:
public class MyData {
public int counter;
}
....
// Some other class
MyData data = new MyData();
data.counter = 5;
System.out.println(data.counter);
Or
public class MyData {
private int counter;
public void setCounter(int counter) {
this.counter = counter;
}
public int getCounter() {
return this.counter;
}
}
....
// Some other class
MyData data = new MyData();
data.setCounter(5);
System.out.println(data.getCounter());
In your code I see:
public int incrementConsumed()
{
//Store value of electricityUse.
}
But this method should just return an integer and have not parameter to get an input to store.
It should be:
public void incrementConsumed(int amount) {
this.amount += amount;
}
I'm concerned about this line:
gasUse = 0 * incrementTime;
If you multiply something to 0 it will be always 0...
Hello So I have a entire class called tractor with different data's stored in it but now I'm suppose to create an object call tractor with a zero parameter constructor but This is the code I have so far and its giving em errors
First off this my Tractor Class which is in a different file:
import java.util.Scanner;
class Tractor
{
private int RentalRate;
private int RentalDays;
private int VehicleID;
private int RentalProfit;
public void setRentalRate(int r)
{
Scanner input = new Scanner(System.in);
System.out.println("What's the Rental Rate?");
int num = input.nextInt();
num = r;
if(r<0 || r >1000)
RentalRate = r;
RentalRate= 1;
}
public int getRentalRate()
{
return RentalRate;
}
public void setVehicleID(int v)
{
Scanner input = new Scanner(System.in);
System.out.println("What's the vehicleID?");
int num1 = input.nextInt();
num1 = v;
if(v<0)
VehicleID = v;
VehicleID = 1;
}
public int getVehicleID()
{
return VehicleID;
}
public void setRentalDays(int d)
{
Scanner input = new Scanner(System.in);
System.out.println("How many rental days?");
int num2 = input.nextInt();
num2 = d;
if(d<0)
RentalDays = d;
RentalDays = 1;
}
public int getRentalDays()
{
return RentalDays;
}
public String toString()
{
String str;
str = "RentalDays:" + RentalDays +"\nRenalRate:" + RentalRate + "\nVehicleID " + VehicleID;
return str;
}
public void RentalProfit(int RentalRate, int RentalDays)
{
RentalProfit = RentalRate * RentalDays;
}
}
import java.util.Scanner;
public class testTractor
{
public static void main(String[] args)
{
public tractor()
{
this.RentalDays = d;
this.RentalRate = r;
this.VehicleID = v;
}
}
}
The error is :
testTractor.java:7: error: illegal start of expression
public tractor()
^
testTractor.java:7: error: ';' expected
public tractor()
^
2 errors
You have compilation errors. You need to first declare the Tractor class then add the constructor inside it. One way to do is declare in a separate file. Also in Java unless you had defined d you couldnt have assigned it. Maybe you wanted to assign the day as a String look in the examples I provide below.
You need to to first create a file call Tractor.java and then define variables there. For example contents of Tractor.java:
public class Tractor {
String rentaldays,someOtherValue;
public Tractor(){
rentaldays ="monday";
someOtherValue="value";
}
//or
public Tractor(String rentalDays){
this.rentaldays = rentalDays;
someOtherValue = "asf";
}
}
Then in your main method You can do Tractor trac = new Tractor(); or Tractor trac = new Tractor("tuesday"); also after that you can print the rentaldays of trac using System.out.println(trac.rentaldays);
From the looks of it you will probably be making a tractor rental system. In that case, rentalDays may be an array of Strings. And then you would have an array of Tractor objects to store in the rental system. You can look at these terms and keywords to point you in the right direction.
You are defining it wrong, define your methods inside class then call them in main() method.
class Test{
public void greeting(){
System.out.print("hello to JAVA..");
}
public static void main(String[] args){
Test testObj = new Test();
testObj.greeting();
}
}
you use an illegal of java syntax, if you already have class tractor in your project. for calling it to in other class, try below code
public class TestTractor(){
Tractor objTractor;
public static void main(String[] args){
//create new tractor object with no parameter
objTractor = new Tractor();
//create new tractor object with parameter
objTractor = new Tractor(parameter here);
//do some action of object here
...........
}
}
//This is just a sample
in your tractor class add below code
public tractor()
{
this.RentalDays = d;
this.RentalRate = r;
this.VehicleID = v;
}
And keep your TestTractor class as
public class TestTractor(){
public static void main(String[] args){
Tractor objTractor = new Tractor();
// objTractor.yourMethodName
}
}
I am finally setting out on my own instead of following courses online and trying to create something on my own, it's just a simple text based dungeon type of game.
However I know I'm messing up when I'm passing in the new values from one class to another class, the class where I try to set the values to pass to another
package com.company;
import java.util.Random;
import java.util.Scanner;
public class CharBuilder {
static public Random randNum = new Random();
static public Scanner sc = new Scanner(System.in);
private String mCharacterName;
private int mStrength = 6;
private int mIntelligence = 6;
private int mConstitution = 6;
private int mDexterity = 6;
private int mHitPoints = 40;
private int mManaPoints = 40;
private String mCharClass;
private CharBuilder hero;
public CharBuilder(String charClass,int str, int intl, int con, int dex, int hp, int mp) {
mCharClass = charClass;
mStrength = str;
mIntelligence = intl;
mConstitution = con;
mDexterity = dex;
mHitPoints = hp;
mManaPoints = mp;
}
public CharBuilder() {
}
public CharBuilder(String charClass) {
mCharClass = charClass;
}
public void characterNameCreator() {
System.out.println("Greetings, what is your name adventurer? ");
mCharacterName = sc.nextLine();
System.out.printf("I see, so your name is %s very well, very well \n", mCharacterName);
}
public void createHero() {
hero = new CharBuilder(mCharClass,mStrength,mIntelligence,mConstitution,mDexterity,mHitPoints,mManaPoints);
String acceptedAnswers = "warrior wizard thief";
System.out.printf("%s would you say you are more of a warrior, wizard or more of the thievery type \n", mCharacterName);
String classAnswer = sc.nextLine();
boolean isAcceptableClass = classAnswer.contains(acceptedAnswers);
do {
if (classAnswer.equalsIgnoreCase("warrior")) {
mCharClass = "warrior";
hero.setStr(mStrength + 3);
hero.setIntelligence(mIntelligence - 1);
hero.setmConstitution(mConstitution + 4);
hero.setmDexterity(mDexterity + 1);
hero.setHitPoints(mHitPoints + 20);
hero.setManaPoints(mManaPoints - 10);
} else if (classAnswer.equalsIgnoreCase("Wizard")) {
mCharClass = "wizard";
hero.setStr(mStrength -1);
hero.setIntelligence(mIntelligence + 3);
hero.setmConstitution(mConstitution + 2);
hero.setmDexterity(mDexterity);
hero.setHitPoints(mHitPoints - 10);
hero.setManaPoints(mManaPoints + 30);
} else if (classAnswer.equalsIgnoreCase("thief") || classAnswer.equalsIgnoreCase("thievery")) {
mCharClass = "thief";
hero.setStr(mStrength + 2);
hero.setIntelligence(mIntelligence + 1);
hero.setmConstitution(mConstitution + 1);
hero.setmDexterity( mDexterity + 5);
hero.setHitPoints(mHitPoints + 10);
hero.setManaPoints(mManaPoints + 10);
} else {
System.out.println("I'm sorry, that is not an acceptable class, please pick warrior, wizard, or thief");
createHero();
}
}while (isAcceptableClass);
}
public int getStrength() {
return mStrength;
}
public int getIntelligence() {
return mIntelligence;
}
public int getConsitution() {
return mConstitution;
}
public int getDex() {
return mDexterity;
}
public int getHP() {
return mHitPoints;
}
public int getMP() {
return mManaPoints;
}
public CharBuilder getHero() {
return hero;
}
public void setStr(int str) {
mStrength = str;
}
public void setIntelligence(int intl) {
mIntelligence = intl;
}
public void setmConstitution(int con) {
mConstitution = con;
}
public void setmDexterity(int dex) {
mDexterity = dex;
}
public void setHitPoints( int hitPoints) {
mHitPoints = hitPoints;
}
public void setManaPoints( int manaPoints) {
mManaPoints = manaPoints;
}
public void setmCharClass(String charClass) {
mCharClass = charClass;
}
}
and the class where I'm trying to pass the variables into doesn't seem to be getting anything as it is giving me a nullPointerException so I know there's no value when I ask it go it, and I've included that class below,
package com.company;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class Combat {
Scanner sc = CharBuilder.sc;
Random randNum = CharBuilder.randNum;
List<Enemy> enemyList = new Enemy().createList();
Enemy enemy = enemyList.get(randNum.nextInt(enemyList.size()));
CharBuilder character = new CharBuilder().getHero();
int charStrength = character.getStrength();
int charHp = character.getHP();
int enemyHp = enemy.getHP();
int enemyStr =enemy.getStr();
String enemyName = enemy.getName();
public void initiateCombat() {
System.out.printf("A %s appears, it has %d hitpoints, and it's strength is %s \n", enemyName, enemyHp, enemyStr);
}
public void playersTurn() {
System.out.println("It is your turn, your available actions are attack, or use a skill");
String actionAnswer = sc.nextLine();
if (actionAnswer.equalsIgnoreCase("attack")) {
enemyHp -= charStrength;
System.out.printf("You attack the enemy, doing %s damage, the enemy currently has %s hp left \n", charStrength,
enemyHp);
}
else {
System.out.println("Sorry, please choose attack or skill ");
playersTurn();
}
}
public void enemyTurn() {
charHp -= enemyStr;
System.out.printf("It is the enemy's turn, it attacks doing %s damage, your current hp is %s \n", enemyStr, charHp);
}
public void combat() {
while(enemyHp >= 0 && charHp >= 0) {
initiateCombat();
playersTurn();
if (enemyHp <= 0) {
System.out.println("You have defeated the enemy, congratulations");
break;
}
enemyTurn();
}
}
}
any tips for a new guy on what I am doing wrong, and how I can get these values over? I know that I could just declare the hero static but is there a better way?
I'm getting NullPointerException in the first possible area where they try to pull data from the CharBuilder class. Which is
int charStrength = character.getStrength();
You need to call createHero() on a CharBuilder before you call getHero() in your constructor.
Your code should be,
List<Enemy> enemyList = new Enemy().createList();
Enemy enemy = enemyList.get(randNum.nextInt(enemyList.size()));
CharBuilder cb = new CharBuilder();
cb.createHero();
CharBuilder character = cb.getHero();
int charStrength = character.getStrength();
int charHp = character.getHP();
int enemyHp = enemy.getHP();
int enemyStr =enemy.getStr();
String enemyName = enemy.getName();
The reason for this is because you need to execute createHero() in order to initialize the hero object.
Further go more on this, you are initializing CharBuilder inside CharBuilder which is not a good practice when we think in terms of object orientation. One alternative is to use the singleton pattern here.
Lets see why you have NPE issue:
Take a look at here
public CharBuilder() {
}
The first constructor is a default constructor. It only initializes the bare minimum and lets users set the rest with getters and setters.
CharBuilder character = new CharBuilder().getHero();
some setters is missing here?
int charStrength = character.getStrength();
As you see in your code, you did not set anything to get it after wards
In addition, There are three common reasons to define a default constructor:
To construct an object with default values.
To initialize an object that doesn't need parameters in that initialization process.
To redefine the scope of the constructor. Making the constructor private will prevent anyone but the class itself from constructing an
object.
If you want to make sure that any instance created is always valid and any member variables are always initialized,then you would define the constructor which initializes all the required member variables.
In your case, you can use createHero function before getHero because createHero sets the values up.
Suggestion:
Plaese take a look at builder pattern for designing a better class
More Info About Builder Pattern
As has already been pointed out, you are not calling createHero, which generates the instance of CharBuilder which getHero returns. Thus returning a null value.
The problem seems to steam from a misunderstanding of what a builder should do. A builder should take raw material and build something, it shouldn't return a copy of it self.
For example...
public class CharBuilder {
static public Random randNum = new Random();
private String mCharacterName;
private int mStrength = 6;
private int mIntelligence = 6;
private int mConstitution = 6;
private int mDexterity = 6;
private int mHitPoints = 40;
private int mManaPoints = 40;
private String mCharClass;
private String classType;
public Character createHero() {
// Valid the properties you have been given...
if ("warrior".equalsIgnoreCase(classType)) {
mCharClass = "warrior";
mStrength = mStrength + 3;
mIntelligence = mIntelligence - 1;
mConstitution = mConstitution + 4;
mDexterity = mDexterity + 1;
mHitPoints = mHitPoints + 20;
mManaPoints = mManaPoints - 10;
} else if ("Wizard".equalsIgnoreCase(classType)) {
mCharClass = "wizard";
mStrength = (mStrength - 1);
mIntelligence = (mIntelligence + 3);
mConstitution = (mConstitution + 2);
mDexterity = (mDexterity);
mHitPoints = (mHitPoints - 10);
mManaPoints = (mManaPoints + 30);
} else if ("thief".equalsIgnoreCase(classType) || "thievery".equalsIgnoreCase(classType)) {
mCharClass = "thief";
mStrength = (mStrength + 2);
mIntelligence = (mIntelligence + 1);
mConstitution = (mConstitution + 1);
mDexterity = (mDexterity + 5);
mHitPoints = (mHitPoints + 10);
mManaPoints = (mManaPoints + 10);
} else {
throw new UnsupportedOperationException("Unknown class");
}
return new DefaultCharacter(mCharacterName, mStrength, mIntelligence, mConstitution, mDexterity, mHitPoints, mManaPoints, mCharClass);
}
public CharBuilder setCharacterName(String mCharacterName) {
this.mCharacterName = mCharacterName;
return this;
}
public CharBuilder setStrength(int mStrength) {
this.mStrength = mStrength;
return this;
}
public CharBuilder setIntelligence(int mIntelligence) {
this.mIntelligence = mIntelligence;
return this;
}
public CharBuilder setConstitution(int mConstitution) {
this.mConstitution = mConstitution;
return this;
}
public CharBuilder setDexterity(int mDexterity) {
this.mDexterity = mDexterity;
return this;
}
public CharBuilder setHitPoints(int mHitPoints) {
this.mHitPoints = mHitPoints;
return this;
}
public CharBuilder setManaPoints(int mManaPoints) {
this.mManaPoints = mManaPoints;
return this;
}
public CharBuilder setCharClass(String mCharClass) {
this.mCharClass = mCharClass;
return this;
}
public CharBuilder setClassType(String classType) {
this.classType = classType;
return this;
}
}
You can use method chaining to make it easier to call, for example
Character character = new CharBuilder().
setCharClass("Wizard").
setCharacterName("Bob").
setConstitution(10).
setDexterity(10).
setHitPoints(10).
setIntelligence(10).
setManaPoints(10).
setStrength(10).
createHero();
The builder shouldn't be asking questions of the user, this information should already have been obtained and simply given to the builder. You should only call the methods which you need in order to build character, so many of the methods in the above example might be omitted in favor of default values
Character character = new CharBuilder().
setCharClass("Wizard").
setCharacterName("Bob").
createHero();
The builder should validate the properties it has been given and throw an Exception if one or required properties are missing (like the name or class)
I, personally, like to work with interfaces, rather then implementations, it allows you to define the public contract that a object can have, for example...
public interface Character {
public String getCharacterName();
public int getStrength();
public int getIntelligence();
public int getConstitution();
public int getDexterity();
public int getHitPoints();
public int getanaPoints();
public String getCharClass();
}
Which can be wrapped in
public class DefaultCharacter implements Character {
private final String mCharacterName;
private final int mStrength;
private final int mIntelligence;
private final int mConstitution;
private final int mDexterity;
private final int mHitPoints;
private final int mManaPoints;
private final String mCharClass;
public Character(String mCharacterName, int mStrength, int mIntelligence, int mConstitution, int mDexterity, int mHitPoints, int mManaPoints, String mCharClass) {
this.mCharacterName = mCharacterName;
this.mStrength = mStrength;
this.mIntelligence = mIntelligence;
this.mConstitution = mConstitution;
this.mDexterity = mDexterity;
this.mHitPoints = mHitPoints;
this.mManaPoints = mManaPoints;
this.mCharClass = mCharClass;
}
public String getCharacterName() {
return mCharacterName;
}
public int getStrength() {
return mStrength;
}
public int getIntelligence() {
return mIntelligence;
}
public int getConstitution() {
return mConstitution;
}
public int getDexterity() {
return mDexterity;
}
public int getHitPoints() {
return mHitPoints;
}
public int getManaPoints() {
return mManaPoints;
}
public String getCharClass() {
return mCharClass;
}
}
Now, because the CharBuilder only says it will return a Character, you can change the physical implementation anyway you like
In this way, it's pretty hard to run into the problem you are having, because either the builder is going to return a valid Character or throw an Exception
Take a closer look at the Builder Pattern for more details
So I'm making a die class that can create and roll a die, return the value and the size. I'm trying to figure out how to tell the program how many of them have been created so that I can have a response be different based on how many there are. IE I want the response from printDie to be Die Value: 5 if there is only one die, and Die 1 Value: 5 if there is more than one.
Here's my code so far.
package com.catalyse.die;
import java.util.Random;
public class Die
{
// instance variables
private int myDieValue;
private int myDieSides;
private Random myRandom;
// Dice Class Constructors
public Die()
{
this.myDieValue = 1;
this.myDieSides = 4;
}
public Die(int numSides)
{
if ((numSides < 4) || (numSides > 100)) {
System.out.println("Error! You cannot have more than 100 sides or less than four!");
System.exit(0);
}
else {
myDieSides = numSides;
}
}
// getter methods
public int getDieSides()
{
return myDieSides;
}
public int getDieValue()
{
return myDieValue;
}
// setter methods
private void setDieSides(int newNumSides)
{
myDieSides = newNumSides;
}
public void rollDie()
{
Random rand = new Random();
int i = (rand.nextInt(myDieSides) + 1);
myDieValue = i;
}
public void printDie(int dieNum)
{
if (dieNum == 1) {
System.out.println("Die Value: "+myDieValue);
}
else {
System.out.println("Die "+dieNum+" Value: "+myDieValue);
}
}
}
You can have static field in your class which could be incremented in the constructor always. The reason why is it should be static is because, static fields are shared by all instances of a class, thus a local copy of the field won't be created for each of the instances you create.
private static int counter = 0;
public Die()
{
counter++;
// Other stuffs
}
// Have a getter method for the counter so that you can
// get the count of instances created at any point of time
public static int getCounter() {
return counter;
}
And then you can call the above method in your calling method like this
void someMethodInAnotherClass() {
int instanceCount = Die.getCounter(); // You need to call static method using the Class name
// other stuffs.
}
Use an static member, that is a 'class' variable, not a 'instance' variable:
private static int count = 0;
In the constructor:
public Die()
{
count++;
this.myDieValue = 1;
this.myDieSides = 4;
}
And a getter:
public static int getCount() {
return count;
}
Use a static variable
public class Die{
static int dieCount = 0;
public Die(){
dieCount++;
}
}
Every time a Die object is created, the count will increase
public static void main(String[] args){
Die die1 = new Die();
Die die2 = new Die();
int count = Die.dieCount;
}
See what is my solution for counting objects in my application
import java.util.Map;
import java.util.TreeMap;
public abstract class ObjectCounter {
private static Map<String, Long> classNameCount = new TreeMap<String, Long>();
public ObjectCounter() {
String key = this.getClass().getName();
if (classNameCount.containsKey(key)) {
classNameCount.put(key, classNameCount.get(key) + 1);
} else {
classNameCount.put(key, 1L);
}
}
public static <T extends ObjectCounter> long getCount(Class<T> c) {
String key = c.getName();
if (classNameCount.containsKey(key)) {
return classNameCount.get(key);
} else {
return 0;
}
}
public static long totalObjectsCreated() {
long totalCount = 0;
for (long count : classNameCount.values()) {
totalCount += count;
}
return totalCount;
}
}
Now extends ObjectCounter class
See below
package com.omt.factory;
public class Article extends ObjectCounter {
}
Now all your other classes are extending Article classes
package com.omt.factory;
public class Bio extends Article {
}
Now here is our main class
package com.omt.factory;
public class Main {
public static void main(String... a) {
Bio b = new Bio();
Bio b1 = new Bio();
Bio b2 = new Bio();
Bio b3 = new Bio();
Bio b4 = new Bio();
com.omt.temp.Bio bio = new com.omt.temp.Bio();
// Total Objects are created
System.out.println("Total Objects Created By Application :" + ObjectCounter.totalObjectsCreated());
// Get Number Of Objects created for class.
System.out.println("[" + com.omt.temp.Bio.class.getName() + "] Objects Created :"
+ ObjectCounter.getCount(com.omt.temp.Bio.class));
System.out.println("[" + Bio.class.getName() + "] Objects Created :" + ObjectCounter.getCount(Bio.class));
System.out.println("[" + Maths.class.getName() + "] Objects Created :" + ObjectCounter.getCount(Maths.class));
}
}
From this article
I am trying to return 2 values from a Java method but I get these errors. Here is my code:
// Method code
public static int something(){
int number1 = 1;
int number2 = 2;
return number1, number2;
}
// Main method code
public static void main(String[] args) {
something();
System.out.println(number1 + number2);
}
Error:
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - missing return statement
at assignment.Main.something(Main.java:86)
at assignment.Main.main(Main.java:53)
Java Result: 1
Instead of returning an array that contains the two values or using a generic Pair class, consider creating a class that represents the result that you want to return, and return an instance of that class. Give the class a meaningful name. The benefits of this approach over using an array are type safety and it will make your program much easier to understand.
Note: A generic Pair class, as proposed in some of the other answers here, also gives you type safety, but doesn't convey what the result represents.
Example (which doesn't use really meaningful names):
final class MyResult {
private final int first;
private final int second;
public MyResult(int first, int second) {
this.first = first;
this.second = second;
}
public int getFirst() {
return first;
}
public int getSecond() {
return second;
}
}
// ...
public static MyResult something() {
int number1 = 1;
int number2 = 2;
return new MyResult(number1, number2);
}
public static void main(String[] args) {
MyResult result = something();
System.out.println(result.getFirst() + result.getSecond());
}
Java does not support multi-value returns. Return an array of values.
// Function code
public static int[] something(){
int number1 = 1;
int number2 = 2;
return new int[] {number1, number2};
}
// Main class code
public static void main(String[] args) {
int result[] = something();
System.out.println(result[0] + result[1]);
}
You could implement a generic Pair if you are sure that you just need to return two values:
public class Pair<U, V> {
/**
* The first element of this <code>Pair</code>
*/
private U first;
/**
* The second element of this <code>Pair</code>
*/
private V second;
/**
* Constructs a new <code>Pair</code> with the given values.
*
* #param first the first element
* #param second the second element
*/
public Pair(U first, V second) {
this.first = first;
this.second = second;
}
//getter for first and second
and then have the method return that Pair:
public Pair<Object, Object> getSomePair();
You can only return one value in Java, so the neatest way is like this:
return new Pair<Integer>(number1, number2);
Here's an updated version of your code:
public class Scratch
{
// Function code
public static Pair<Integer> something() {
int number1 = 1;
int number2 = 2;
return new Pair<Integer>(number1, number2);
}
// Main class code
public static void main(String[] args) {
Pair<Integer> pair = something();
System.out.println(pair.first() + pair.second());
}
}
class Pair<T> {
private final T m_first;
private final T m_second;
public Pair(T first, T second) {
m_first = first;
m_second = second;
}
public T first() {
return m_first;
}
public T second() {
return m_second;
}
}
Here is the really simple and short solution with SimpleEntry:
AbstractMap.Entry<String, Float> myTwoCents=new AbstractMap.SimpleEntry<>("maximum possible performance reached" , 99.9f);
String question=myTwoCents.getKey();
Float answer=myTwoCents.getValue();
Only uses Java built in functions and it comes with the type safty benefit.
Use a Pair/Tuple type object , you don't even need to create one if u depend on Apache commons-lang. Just use the Pair class.
you have to use collections to return more then one return values
in your case you write your code as
public static List something(){
List<Integer> list = new ArrayList<Integer>();
int number1 = 1;
int number2 = 2;
list.add(number1);
list.add(number2);
return list;
}
// Main class code
public static void main(String[] args) {
something();
List<Integer> numList = something();
}
public class Mulretun
{
public String name;;
public String location;
public String[] getExample()
{
String ar[] = new String[2];
ar[0]="siva";
ar[1]="dallas";
return ar; //returning two values at once
}
public static void main(String[] args)
{
Mulretun m=new Mulretun();
String ar[] =m.getExample();
int i;
for(i=0;i<ar.length;i++)
System.out.println("return values are: " + ar[i]);
}
}
o/p:
return values are: siva
return values are: dallas
I'm curious as to why nobody has come up with the more elegant callback solution. So instead of using a return type you use a handler passed into the method as an argument. The example below has the two contrasting approaches. I know which of the two is more elegant to me. :-)
public class DiceExample {
public interface Pair<T1, T2> {
T1 getLeft();
T2 getRight();
}
private Pair<Integer, Integer> rollDiceWithReturnType() {
double dice1 = (Math.random() * 6);
double dice2 = (Math.random() * 6);
return new Pair<Integer, Integer>() {
#Override
public Integer getLeft() {
return (int) Math.ceil(dice1);
}
#Override
public Integer getRight() {
return (int) Math.ceil(dice2);
}
};
}
#FunctionalInterface
public interface ResultHandler {
void handleDice(int ceil, int ceil2);
}
private void rollDiceWithResultHandler(ResultHandler resultHandler) {
double dice1 = (Math.random() * 6);
double dice2 = (Math.random() * 6);
resultHandler.handleDice((int) Math.ceil(dice1), (int) Math.ceil(dice2));
}
public static void main(String[] args) {
DiceExample object = new DiceExample();
Pair<Integer, Integer> result = object.rollDiceWithReturnType();
System.out.println("Dice 1: " + result.getLeft());
System.out.println("Dice 2: " + result.getRight());
object.rollDiceWithResultHandler((dice1, dice2) -> {
System.out.println("Dice 1: " + dice1);
System.out.println("Dice 2: " + dice2);
});
}
}
You don't need to create your own class to return two different values. Just use a HashMap like this:
private HashMap<Toy, GameLevel> getToyAndLevelOfSpatial(Spatial spatial)
{
Toy toyWithSpatial = firstValue;
GameLevel levelToyFound = secondValue;
HashMap<Toy,GameLevel> hm=new HashMap<>();
hm.put(toyWithSpatial, levelToyFound);
return hm;
}
private void findStuff()
{
HashMap<Toy, GameLevel> hm = getToyAndLevelOfSpatial(spatial);
Toy firstValue = hm.keySet().iterator().next();
GameLevel secondValue = hm.get(firstValue);
}
You even have the benefit of type safety.
Return an Array Of Objects
private static Object[] f ()
{
double x =1.0;
int y= 2 ;
return new Object[]{Double.valueOf(x),Integer.valueOf(y)};
}
In my opinion the best is to create a new class which constructor is the function you need, e.g.:
public class pairReturn{
//name your parameters:
public int sth1;
public double sth2;
public pairReturn(int param){
//place the code of your function, e.g.:
sth1=param*5;
sth2=param*10;
}
}
Then simply use the constructor as you would use the function:
pairReturn pR = new pairReturn(15);
and you can use pR.sth1, pR.sth2 as "2 results of the function"
You also can send in mutable objects as parameters, if you use methods to modify them then they will be modified when you return from the function. It won't work on stuff like Float, since it is immutable.
public class HelloWorld{
public static void main(String []args){
HelloWorld world = new HelloWorld();
world.run();
}
private class Dog
{
private String name;
public void setName(String s)
{
name = s;
}
public String getName() { return name;}
public Dog(String name)
{
setName(name);
}
}
public void run()
{
Dog newDog = new Dog("John");
nameThatDog(newDog);
System.out.println(newDog.getName());
}
public void nameThatDog(Dog dog)
{
dog.setName("Rutger");
}
}
The result is:
Rutger
You can create a record (available since Java 14) to return the values with type safety, naming and brevity.
public record MyResult(int number1, int number2) {
}
public static MyResult something() {
int number1 = 1;
int number2 = 2;
return new MyResult(number1, number2);
}
public static void main(String[] args) {
MyResult result = something();
System.out.println(result.number1() + result.number2());
}
First, it would be better if Java had tuples for returning multiple values.
Second, code the simplest possible Pair class, or use an array.
But, if you do need to return a pair, consider what concept it represents (starting with its field names, then class name) - and whether it plays a larger role than you thought, and if it would help your overall design to have an explicit abstraction for it. Maybe it's a code hint...
Please Note: I'm not dogmatically saying it will help, but just to look, to see if it does... or if it does not.