Իմ բլոգի «Բարձր կարգի ֆունկցիաներ և անանուն ֆունկցիաներ» գրառման մեջ ես ֆունկցիայի ինտեգրալի թվային հաշվման օրինակով համեմատել էի 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