📜 ⬆️ ⬇️

Functional programming in Java

Now there are new fashionable languages ​​using the functional programming paradigm. However, in regular java
You can use functions to describe the behavior of objects. And it can be done completely within the syntax of Java.

I published a Java library that allows you to bind objects through functions (see https://code.google.com/p/tee-binding/ )

image
')


Class descriptions


public class It ‹E›
- the main class, contains a link to an object of any type and updates all the links when values ​​change in one of the instances. Example
It‹String› a1 = new It‹String›().value("A"); It‹String› a2 = new It‹String›().value("B"); System.out.println("a1: "+a1.value()+", a2: "+a2.value()); a1.bind(a2); System.out.println("a1: "+a1.value()+", a2: "+a2.value()); a1.value("C"); System.out.println("a1: "+a1.value()+", a2: "+a2.value()); a2.value("D"); System.out.println("a1: "+a1.value()+", a2: "+a2.value()); 


result:

 a1: A, a2: B a1: B, a2: B a1: C, a2: C a1: D, a2: D 


The Number, Note, Toggle classes are derived from the It class for storing values ​​of a particular type (for Double, String, and Boolean, respectively) and contain methods for specifying binding using functions. Example:

  Numeric c = new Numeric().value(0); Numeric f = c.multiply(9.0).divide(5.0).plus(32.0); System.out.println("f: " + f.value() + ", c: " + c.value()); System.out.println("/let f = 100 "); f.value(100); System.out.println("f: " + f.value() + ", c: " + c.value()); System.out.println("/let c = 100 "); c.value(100); System.out.println("f: " + f.value() + ", c: " + c.value()); 


result:

 f: 32.0, c: 0.0 /let f = 100 f: 100.0, c: 37.77777777777778 /let c = 100 f: 212.0, c: 100.0 


as you can see, this is the function of converting temperature from Celsius to Fahrenheit (F '= C' * 9/5 + 32). From the definition of a variable
Numeric f = c.multiply(9.0).divide(5.0).plus(32.0);

it is quite obvious. It can also be noted that function binding is bidirectional.

Note: pseudo-ops of a function are calculated sequentially without taking into account the priority of operations.

For more complex cases, you can use the class Fork. It allows you to use in binding conditions, example:

  System.out.println("/n = -10"); Numeric n = new Numeric().value(-10); Note r = new Note().bind(new Fork‹String›() .condition(new Toggle().less(n, -5)) .then("Frost") .otherwise(new Fork‹String›() .condition(new Toggle().less(n, +15)) .then("Cold") .otherwise(new Fork‹String›() .condition(new Toggle().less(n, +30)) .then("Warm") .otherwise("Hot") ))); System.out.println(r.value()); System.out.println("/let n = +10"); n.value(10); System.out.println(r.value()); System.out.println("/let n = +20"); n.value(20); System.out.println(r.value()); System.out.println("/let n = +40"); n.value(40); System.out.println(r.value()); 

result:
 /n = -10 Frost /let n = +10 Cold /let n = +20 Warm /let n = +40 Hot 


The condition record is quite obvious, depending on the value of the variable n, the text Frost, Cold, Warm or Hot is entered into the variable r.

Library application


Unfortunately, binding and functions cannot be used directly. Consider the modifications needed to apply binding in Swing:

 class BindableLabel extends JLabel { private Note bindableValue = new Note().value("").afterChange(new Task() { @Override public void job() { if (bindableValue != null) { setText(bindableValue.value()); } } }); public Note bindableValue() { return bindableValue; } public BindableLabel() { super(); } } 


This class extends the standard JLabel. It allows you to update the link text of the label with a variable of type Note.
For editable Swing components, you also have to add a ChangeListener. An example of defining the behavior of components from a form in the screenshot:
 void bindComponents() { Numeric celsius = new Numeric().value(0); Numeric fahrenheit = celsius.multiply(9.0).divide(5.0).plus(32.0); fahrenheitSlider.bindableValue().bind(fahrenheit); fahrenheitSpinner.bindableValue().bind(fahrenheit); celsiusSlider.bindableValue().bind(celsius); celsiusSpinner.bindableValue().bind(celsius); 


- as you can see, it takes only a few lines and when you edit any value in the form (or move the slider to the slider), the other components instantly update their state.

Source: https://habr.com/ru/post/127076/


All Articles