This question already has answers here:
How to create change listener for variable?
(5 answers)
Closed 1 year ago.
Can I somehow do that?
public class Test {
public int a = 5;
public int b = 10;
public void change() {
this.a += 1;
this.b += 1;
}
}
Test test1 = new Test();
Test test2 = new Test();
test.valueChanged((a, b) -> {
System.out.println(a + b);
});
test2.valueChanged((a, b) -> {
System.out.println(a - b);
};
test1.change();
// System.out.println: 17
test2.change();
// System.out.println: -5
I'd like to have functions which is called whenever values are changed.
I will have Test created more times and I would like to have different valueChanged as well.
If you wish to be notified when a field changes, then the best way to go is to make that field private and create a setter and getter method for that field. This allows you to put extra code in the setter that will execute when the value will be changed. Example:
public class Test {
private int val;
public void setVal(int val) {
this.val = val;
// Put code here that you want to execute when the value has changed.
}
public int getVal() {
return this.val;
}
}
Related
This question already has answers here:
Java Pass Method as Parameter
(17 answers)
How to pass a function as a parameter in Java? [duplicate]
(8 answers)
Closed 3 years ago.
I have a class with bunch of methods. In another class, I need to write a method, that handles the input values. To that method, I want to pass the method of the class that I want to call. How can we do that with Java after 1.8?
There are similar questions already, but those usually assume that we can use an interface with a single method, therefore can use lambda expressions, etc.
class MyClass {
public Object myToString(String a) {
return new String(a);
}
public Object myToString(String a, String b) {
return new String(a + ", " + b);
}
public Object mySum(int a) {
return new Integer(a);
}
public Object mySum(int a, int b) {
return new Integer(a + b);
}
}
class Test {
public Object handleInputs(MyClass myClass, MethodAsParameter theMethod, List<Object> inputs) {
if (type of inputs are Strings) {
myClass.myToString(inputs.get(0));
} else if (.....) {
myClass.mySum(inputs.get(0));
}
}
}
Since Java 8 you can use method reference. Method references can be assigned to Function<A, B> functional interface variables and their subclasses.
For example, method with such signature:
class Test {
public static int DoSomething(String s) {...}
}
can be assigned to a Function<String, Integer> variable like:
Function<String, Integer> method = Test::DoSomething;
and then called:
int result = method.apply("Hello!");
So with small improvements in your code, this is the way you can use your methods as method references and passed to other function as parameters.
class MyClass {
public static String myToString(String a, String b) {
return a + ", " + b;
}
//notice the boxing in here
public static int mySum(int a, int b) {
return a + b;
}
//not kind of an revolutionary function, just for demonstration
public static<T> T Invoke(BinaryOperator<T> bo, T o1, T o2) {
return bo.apply(o1, o2);
}
public static void main(String[] args) {
int sum = Invoke(MyClass::mySum, 10, 20);
String str = Invoke(MyClass::myToString, "a", "b");
System.out.println(sum);
System.out.println(str);
}
}
I think something like this is as far as you would get:
import java.util.List;
import java.util.Arrays;
import java.util.function.Function;
import java.util.function.BiFunction;
class MyClass {
public Object myToString(String a) {
return new String(a);
}
public Object myToString(String a, String b) {
return new String(a + ", " + b);
}
public Object mySum(int a) {
return Integer.valueOf(a);
}
public Object mySum(int a, int b) {
return Integer.valueOf(a + b);
}
}
public class MethodParams {
public static Object handleInputs(Function<Object,Object> method, List<Object> inputs) {
return method.apply(inputs.get(0));
}
public static Object handleInputs(BiFunction<Object,Object,Object> method, List<Object> inputs) {
return method.apply(inputs.get(0), inputs.get(1));
}
public static void main(String args[]) {
MyClass mc = new MyClass();
String str = (String)handleInputs((a) -> mc.myToString((String)a), Arrays.asList("string"));
System.out.println(str); // string
Integer sum = (Integer)handleInputs((a) -> mc.mySum((int)a), Arrays.asList(1));
System.out.println(sum); // 1
Integer sum2 = (Integer)handleInputs((a,b) -> mc.mySum((int)a, (int)b), Arrays.asList(1, 2));
System.out.println(sum2); // 3
}
}
Not very nice, but at least you have some leeway as to which method you want to use. Code as demonstrated here has lots of casts due to using Objects - using generic types as demonstrated by t2dohx is better way of doing this, but even further from your question.
Here is a simple example:
public class TestMain {
public static void main(String [] args) {
Long a = 15L, b = 20L;
Long sum = combineTwoNumbers(a, b, (p1, p2) -> p1 + p2);
Long product = combineTwoNumbers(a, b, (p1, p2) -> p1 * p2);
System.out.println("Sum is " + sum);
System.out.println("Product is " + product);
}
public static Long combineTwoNumbers(Long a, Long b, BiFunction <Long, Long, Long> combiner) {
return combiner.apply(a, b);
}
}
Here, the functional parameter is BiFunction, which takes two parameters in input and returns an output. Specifically, it takes two long numbers and produces a third one as a result. The name of the method is kept generic so that it can cover more instances of different functions that may take place. In our example we are passing a sum and a product function as you can see.
I have a function like that
Class Return_two{
public static void main(String args[]){
int b=0;// Declare a variable
int a []= new int[3];// Declare an array [both are return at the end of the user define function fun()]
Return_two r=new Return_two();
int result_store= r.fun(a,b);//where should I store the result meaning is it a normal variable or an array where I store the result?
}
public int [] fun (int[] array,int var)//may be this is not a good Return type to returning an array with a variable so what will be change in return type?
{
for(int counter=0;counter <array.length;counter++)
{ var=var+counter;
}
return( array,var);// Here how could I return this two value in main function?
}
}
Now, here lies my question. I want to return an array with a variable as I written above.But as I know one can return a array or a variable but not both. Or one can return one or more variable make those variable as a array element. But how can one return an array with an variable in main function?
If you want to create multiple values, wrap them in an object.
(I'm not able to come up with a meaningful name from what you have posted)
class Result {
private int[] a;
private int b;
public Result(int[] a, int b) {
this.a = a;
this.b = b;
}
//Getters for the instance variables
public int[] getA() {
return a;
}
public int getB() {
return b;
}
}
At the end of fun
return new Result(array, var);
Some best practices:
Don't declare variable names with same name as a parameter (a in fun)
In the above Result class, better to create copies on the array a to avoid mutations outside the class.
If possible, don't use arrays and use a List (this would give you a lot of flexibility)
EDIT:
Your caller will look like
Return_two r=new Return_two();
Result result = r.fun(a, b);
result.getA();//Do whatever you want to do with the array
result.getB();//Do whatever you want to do with that variable
With your current version of the (modified) code, why do you want to return the array since it is same as what you pass to the fun method? Returning only the computed var will work for you (and hence the return type can simply be int).
You can also achieve what you do in fun in one line
return (array.length * (array.length - 1)) / 2;
Wrap these properties into a object, say
Public class FunModel
{
public int[] a;
public int b;
}
then you can return an instance of `FunModel`.
Or
you can use `Tuples`
------------------
Futher Explanation
------------------
The return type here should be a model.
This model should have all that you want to return as properties.
You can return this model from your method.
public class FunModel
{
public int[] a;
public int b;
public FunModel(int[] a, int b) {
this.a = a;
this.b = b;
}
}
And the method should return a instance of this model.
public class ReturnTwo {
public static void main(String args[]){
int b=0;
int a []= new int[3];
ReturnTwo returnTwo = new ReturnTwo();
FunModel funModel = returnTwo.fun(a,b);
//other processing
}
public FunModel fun (int[] array,int tempVar)
{
FunModel temp = new FunModel(array,tempVar);
for(int counter=0;counter <array.length;counter++)
{
temp.b = temp.b + counter;
}
return temp;// you return the model with different properties
}
}
This is one of the practice questions of a test:
Write a method which accepts two integer values as input parameters and returns the boolean result true if the sum of the inputs is greater than or equal to 10 (and falseotherwise)
My answer is below but I don't think it looks correct. Can anyone give me a pointer?
public class Bruh{
public static void main (String [] arg){
int a;
int b;
boolean sum = true;
if ( a+b > 10)
System.out.println ("yo");
else{
sum = false;
}
}
}
You only wrote some code in the main method but you did not create one.
In order to do that you need to actually create a method in your Bruh class like:
public static boolean isSumGreaterThan9(int a, int b){
return (a + b) > 9;
}
Than call it from the main method:
public static void main (String [] arg){
int a = 4; // or whatever
int b = 7; // or whatever
System.out.println(isSumGreaterThan9(a, b));
}
You need to put your logic into a method and change your comparison to >= as per the requirement:
public static boolean isSumGreaterThanOrEqualToTen(int a, int b) {
return (a + b) >= 10;
}
final int a, b;
if (condition1) {
a = get(dynamicValues);
b = get(dynamicValues);
}
if (condition2) {
int c = b + a;
display(c);
}
In this type of code the compiler is asking to intialize a and b, which I can't do until the condition1 is met. and a and b being final is mandatory as the values of hours and minutes keep changing.
The above written code is very generalized just to give you an idea of my problem.
UPDATE: The problem here is condition2 is one of the else conditions of condition1. So can't use else statements too.
Dynamic values here are the values like "hrs and mins" which always change. when condition1 is met a and b are intialised with hrs and mins, condition2 will definitely happen after condition1 at some point of time. So the time difference between condition2 and condition1 needs to be calculated.
if condition1 is false a and b remain not initialized. That's why the compiler is complaining. Add the else branch and it will compile correctly
if(condition1)
{
a=cal.get(Calendar.HOUR);
b=cal.get(Calendar.MINUTE);
} else {
a = 0;
b = 0;
}
Forgive me if I have not understood your problem correctly :). It seems to me that perhaps it's easier to wrap up your 'final' variables into an immutable class. Then create an instance of such a class in 'condition1'. Here's what I mean...
import java.util.Scanner;
import java.util.Calendar;
public class ImmutableHourMinute {
private final int a;
private final int b;
public ImmutableHourMinute(final int $a, final int $b){
this.a = $a;
this.b = $b;
}
public int getA() {
return a ;
}
public int getB() {
return b;
}
public static void main(String... args){
// Requirements:
// 1. Hour and minute are set at condition == 1;
// 2. Hour and minutes must never be changed.
System.out.println("Please type 'start':");
Scanner scanner = new Scanner(System.in);
ImmutableHourMinute hourAndMinute = null; // Can be initialized properly later
while(!scanner.nextLine().equals("quit")){
System.out.println("Please enter condition (1 or 2):");
int condition = scanner.nextInt();
if(condition == 1){
Calendar rightNow = Calendar.getInstance();
int a = rightNow.get(Calendar.HOUR);
int b = rightNow.get(Calendar.MINUTE);
System.out.println(String.format("(Creating ImmutableHourMinute(a=%1$d, b=%2$d)", a, b));
hourAndMinute = new ImmutableHourMinute(a, b);
}else if (condition == 2){
display(hourAndMinute.getA() + hourAndMinute.getB());
}
System.out.println("Please enter condition (1 or 2):");
}
}
private static void display(final int displayValue){
System.out.println(String.format("Displaying the time set in condition 1 :%1$d", displayValue));
}
}
And here is a sample of the output:
$ java ImmutableHourMinute
Please type 'start':
start
Please enter condition (1 or 2):
1
(Creating ImmutableHourMinute(a=9, b=56)
Please enter condition (1 or 2):
Please enter condition (1 or 2):
2
Displaying the time set in condition 1 :65
note : such and immutable class already exists(if you're using Java SE 8)...
java.time.LocalDateTime
public class time{
private int a=0;
private int b=0;
public int get()
{
return a+b;
}
public void set()
{
this.a = cal.get(Calendar.HOUR);
this.b = cal.get(Calendar.MINUTE);
}
}
In your main class, call the time class method(out of main method, at very begining),
public final Time t = new Time();
In main method:
if(condition1)
{
t.set();
}
if(condition2)
{
display(t.get());
}
I have been given a piece of code (the class QuestionTwo).
I am asked to state the values of a, b, and c after method mQ2 is invoked on a newly created object of class Q2.
My main.java file
package openuniversity;
public class Main
{
public static void main(String[] args)
{
QuestionTwo qt = new QuestionTwo();
qt.mQ2();
}
}
My QuestionTwo.java class file:
package openuniversity;
public class QuestionTwo
{
int a;
int b = 1;
public void mQ2()
{
{
int c;
int a = 2;
c = a;
}
{
int c;
int a;
c = 3;
a = 4;
}
a++;
}
}
I arrived at:
a: 1
b: 1
c: 3
Note I can also select 'undefined' as an answer?
So would it be 1, 1, undefined as c does not exist outside of the codeblock?
The question:
Study the following code and then select the options from the drop-down lists below that are correct about the values of a, b and c after the method mQ2 is invoked once on a newly created object of class Q2. Note that the answers you choose for a, b and c may or may not be different from each other.
public class Q2
{
int a;
int b = 1;
public void mQ2()
{
{
int c;
int a = 2;
c = a;
}
{
int c;
int a;
c = 3;
a = 4;
System.out.println("c: " + c); //correct place?
}
a++;
}
System.out.println("a: " + a + "b: " + b); // correct place?
}
Since this is homework, I'll restrict my answer to a couple of pointers.
You can verify your solution by printing out the variables after calling mQ2() (hint: you could use System.println() for that).
This is either a trick question or is partially ill-defined (hint: think about which a, b and especially c you're being asked about).
I'd suggest you first print out all the values using System.out.println() after calling mQ2, then step through the code in your mind to try to work out why the values are what they are. Remember that any variable declared is only visible within the scope ({...}s for simplicity), but these variables can have the same name as other variables so they might look like the same even if they're not.
I'd like to particularly point out that c does not exist outside that method.