Իմ բլոգի «Բարձր կարգի ֆունկցիաներ և անանուն ֆունկցիաներ» գրառման մեջ ես ֆունկցիայի ինտեգրալի թվային հաշվման օրինակով համեմատել էի Common Lisp և C++11 լեզվի անանուն ֆունկցիաները։ Այս գրառման մեջ ուզում եմ նույն այդ օրինակը ցույց տալ Java 8 լեզվի անանուն ֆունկցիաների օգտագործմամբ։
Մաթեմատիկական ֆունկցիան, որ կարելի է ինտեգրել, իրականացնում է
MathFunc
ինտերֆեյսը։ Այն սահմանված է MathFunc.java
ֆայլում։
package integral; public interface MathFunc { public double apply( double x ); }Թվային ինտեգրման մեթոդն իրականացնում է
Method
ինտերֆեյսը, որը սահմանված է Method.java
ֆայլում՝ հետևյալ կերպ։
package integral; public interface Method { public double apply( MathFunc f, double a, double b ); }Սահմանեմ
Integral
դասը և սահմանեմ այդ դասի evaluate
մեթոդը, որն արգումենտում սպասում է ինտեգրման մեթոդը, ինտեգրվող ֆունկցիան, ինտեգրման միջակայքը և միջակայքի՝ հատվածների տրոհման գործակիցը։ Հաշվելու եղանակը պարզագույնն է. meth
օբյեկտի apply
մեթոդին են փոխանցվում ինտեգրվող ֆունկցիան և այն փոքր հատվածը, որի վրա նշված թվային մեթոդով հաշվվում է ինտեգրալը։
package integral; public class Integral { public static double evaluate(Method meth, MathFunc func, double left, double right, double epsilon) { double result = 0.0; for( double x = left; x < right; x += epsilon ) result += meth.apply(func, x, x + epsilon); return result; } }Որպեսզի, օրինակ,
Integral
դասի evaluate
ստատիկ մեթոդի օգնությամբ հաշվեմ \(f(x)=3x^2-2x+1\) ֆունկցիայի ինտեգրալը, պետք է նախ՝ \(f(x)\) ֆունկցիան սահմանեմ որպես MathFunc
ինտերֆեյս իրականացնող օբյեկտ, իսկ ինտեգրման մեթոդը, օրինակ սեղանների կանոնը, սահմանեմ որպես Method
ինտերֆեյսն իրականացնող օբյեկտ։Սահմանեմ
Calc
դասը՝ main
մուտքի կետով։
package integral; public class Calc { /**/ public static void main( String[] args ) { // ինտեգրման մեթոդ Method Simple = new Method() { @Override public double apply( MathFunc f, double a, double b ) { return (b - a) * f.apply((b + a) / 2); } }; // ինտեգրվող ֆունկցիա MathFunc Sin = new MathFunc() { @Override public double apply( double x ) { return 3*x*x - 2*x + 1; } }; // ինտեգրալի հաշվումն ու արտածումը double r0 = Integral.evaluate(Simple, Sin, 0, 1, .0001); System.out.println( r0 ); } }Բայց սա հնացած եղանակն է։ Անանուն ֆունկցիաների օգտագործմամբ գրվում է շատ ավելի համառոտ, գեղեցիկ ու հասկանալի կոդ։ Ստորև բերված
main
ֆունկցիայում ինտեգրման մեթոդն ու ինտեգրվող ֆունկցիան evaluate
ֆունկցիային փոխանցված են որպես անանուն ֆունկցիաներ։
package integral; public class Calc { /**/ public static void main( String[] args ) { double r1 = Integral.evaluate( (f,a,b)->(b-a)*f.apply((b+a)/2), (x)-> 3*x*x - 2*x + 1, 0, 1, .0001 ); System.out.println( r1 ); } }
(արգումենտների ցուցակ) -> ֆունկցիայի մարմին
Օրինակ, թվային մոտավոր ինտեգրման սեղանների կանոնի բանաձևը վերը բերված օրինակում սահմանված է ահա այսպես․
(f, a, b) -> (b - a) * f.apply((b + a) / 2)Կարելի է անանուն ֆունկցիան կապել որևէ փոփոխականի հետ, օրինակ, թվային մոտավոր ինտեգրման Սիմպսոնի կանոնի բանաձևը սահմանված է որպես անանուն ֆունկցիա և վերագրված է
simpson
փոփոխականին․
public static Method simpson = (f, a, b) -> ((b - a) / 6) * (f.apply(a) + f.apply(b) + 4*f.apply((a+b)/2));Ինտեգրալը հաշվելիս կարելի է
evaluate
ֆունկցիային փոխանցել simpson
փոփոխականը․
double r2 = Integral.evaluate( simpson, (x)-> 3*x*x - 2*x + 1, 0, 1, .0001 );
Առայժմ այսքանը։ Ես դեռ նոր եմ ուսումնասիրում Java 8-ի անանուն ֆունկցիաները։ Հետքգայում միգուցե նորից անդրադառնամ այս թեմային ու ներկայացնեմ ավելի հետաքրքիր օրինակներ։
No comments:
Post a Comment