乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Java開發(fā)筆記(六十四)靜態(tài)方法引用和實(shí)例方法引用

       印度阿三17 2019-02-25

      前面介紹了方法引用的概念及其業(yè)務(wù)場景,雖然在所列舉的案例之中方法引用確實(shí)好用,但是顯而易見這些案例的適用場合非常狹窄,因?yàn)楸灰玫姆椒ū仨殞儆谕鈱幽涿椒ǎ碙ambda表達(dá)式)的數(shù)據(jù)類型,像isEmpty、contains、startsWith、endsWith、matches、compareTo、compareToIgnoreCase等等無一例外全部歸屬String字符串類型,假使Lambda表達(dá)式輸入?yún)?shù)的數(shù)據(jù)類型并不擁有式子右邊的方法,那么方法引用還能派上用場嗎?
      當(dāng)然Java8憋出方法引用這么一個大招,絕非只想讓它走過場而已,而是要除舊革新深入應(yīng)用。上一篇文章費(fèi)了許多口舌介紹的案例,其實(shí)僅僅涉及到方法引用的其中一個分支——參數(shù)方法引用,該分支顧名思義被引用的方法對應(yīng)于入?yún)⒌臄?shù)據(jù)類型。方法引用還有其它兩個分支,分別是靜態(tài)方法引用和實(shí)例方法引用,接下來依次進(jìn)行詳細(xì)說明。
      首先是靜態(tài)方法引用,所謂靜態(tài)表示被引用的方法乃某個工具類的靜態(tài)方法。為了逐步展開相關(guān)論述,開頭還是先定義一個專屬的計(jì)算器接口,同時該接口也是一個標(biāo)準(zhǔn)的函數(shù)式接口。下面是計(jì)算器接口的定義代碼:

      //定義一個計(jì)算器接口,給算術(shù)類使用
      public interface Calculator {
      
      	// 聲明一個名叫運(yùn)算的抽象方法
      	public double operate(double x, double y);
      }

      可見計(jì)算器接口聲明了一個運(yùn)算方法,該方法有兩個浮點(diǎn)入?yún)?。之所以把運(yùn)算方法當(dāng)作抽象類型,是為了支持動態(tài)指定兩個數(shù)字的運(yùn)算操作,例如可以對這兩個數(shù)字進(jìn)行相加運(yùn)算,或者相乘運(yùn)算,或者求兩數(shù)的最大值,或者求兩數(shù)的最小值等等。為此還要定義一個算術(shù)工具類,在該工具類中編寫calculate方法,將計(jì)算器接口以及兩個操作數(shù)作為calculate方法的輸入?yún)?shù)。這個算術(shù)工具類的角色相當(dāng)于數(shù)組工具類Arrays,它的定義代碼示例如下:

      //定義一個算術(shù)類
      public class Arithmetic {
      
      	// 定義一個靜態(tài)的計(jì)算方法,根據(jù)傳入的計(jì)算器接口,對后面兩個數(shù)字進(jìn)行運(yùn)算
      	public static double calculate(Calculator calculator, double x, double y) {
      		// 這里調(diào)用了計(jì)算器接口的運(yùn)算方法
      		return calculator.operate(x, y);
      	}
      }

      現(xiàn)在輪到外部去調(diào)用算術(shù)類Arithmetic,倘若命令計(jì)算器去求兩個數(shù)字的較大值,則參照Arrays工具的sort方法格式,可編寫如下所示的運(yùn)算代碼(包括匿名內(nèi)部類方式與Lambda表達(dá)式):

      	// 演示靜態(tài)方法的方法引用
      	private static void testStatic() {
      		double result;
      		// 采取匿名內(nèi)部類方式對兩個操作數(shù)進(jìn)行指定運(yùn)算(求較大值)
      		result = Arithmetic.calculate(new Calculator() {
      			@Override
      			public double operate(double x, double y) {
      				return Math.max(x, y);
      			}
      		}, 3, 2);
      		// 采取Lambda表達(dá)式對兩個操作數(shù)進(jìn)行指定運(yùn)算(求較大值)
      		result = Arithmetic.calculate((x, y) -> Math.max(x, y), 3, 2);
      	}

      顯然求最大值用到的max方法屬于Math數(shù)學(xué)函數(shù)庫,不屬于x與y二者的變量類型,并且max還是Math工具的靜態(tài)方法而非實(shí)例方法。盡管此時max方法不符合參數(shù)方法引用,但它恰恰跟靜態(tài)方法引用對上號了,因而Lambda表達(dá)式“(x, y) -> Math.max(x, y)”允許簡寫為“Math::max”。依此類推,通過Arithmetic工具的calculate方法求兩個數(shù)字的較小值,也能代入方法引用“Math::min”;求某個數(shù)字的n次方,可代入方法引用“Math::pow”;求兩個數(shù)字之和,可代入方法引用“Double::sum”。于是在算術(shù)工具中運(yùn)用靜態(tài)方法引用的代碼變成了下面這樣:

      		// 采取雙冒號的方法引用來替換Lambda表達(dá)式中的靜態(tài)方法,求兩數(shù)的較大值
      		result = Arithmetic.calculate(Math::max, 3, 2);
      		System.out.println("兩數(shù)的較大值=" result);
      		// 被引用的方法換成了Math.min,求兩數(shù)的較小值
      		result = Arithmetic.calculate(Math::min, 3, 2);
      		System.out.println("兩數(shù)的較小值=" result);
      		// 被引用的方法換成了Math.pow,求某數(shù)的n次方
      		result = Arithmetic.calculate(Math::pow, 3, 2);
      		System.out.println("兩數(shù)之乘方=" result);
      		// 被引用的方法換成了Double.sum,求兩數(shù)之和
      		result = Arithmetic.calculate(Double::sum, 3, 2);
      		System.out.println("兩數(shù)之和=" result);

      運(yùn)行上述的計(jì)算代碼,輸出兩個數(shù)字的各項(xiàng)運(yùn)算結(jié)果見下:

      兩數(shù)的較大值=3.0
      兩數(shù)的較小值=2.0
      兩數(shù)之乘方=9.0
      兩數(shù)之和=5.0

      要是接著求兩個數(shù)字之差、兩個數(shù)字之積等等,就會發(fā)現(xiàn)不管是Math工具,還是包裝浮點(diǎn)型Double,它們都沒有可用的靜態(tài)方法了。不過這難不倒我們,即使系統(tǒng)不提供,咱也能自己定義相應(yīng)的計(jì)算方法唄。說時遲那時快,熟練的程序員早早準(zhǔn)備好了包括常見運(yùn)算在內(nèi)的數(shù)學(xué)工具類,不但有四則運(yùn)算,還有乘方和開方運(yùn)算,完整的工具類代碼如下所示:

      //定義數(shù)學(xué)工具類
      public class MathUtil {
      
      	// 加法運(yùn)算
      	public double add(double x, double y) {
      		return x y;
      	}
      
      	// 減法運(yùn)算
      	public double minus(double x, double y) {
      		return x-y;
      	}
      
      	// 乘法運(yùn)算
      	public double multiply(double x, double y) {
      		return x*y;
      	}
      
      	// 除法運(yùn)算
      	public double divide(double x, double y) {
      		return x/y;
      	}
      
      	// 取余數(shù)運(yùn)算
      	public double remainder(double x, double y) {
      		return x%y;
      	}
      
      	// 取兩數(shù)的較大值
      	public double max(double x, double y) {
      		return Math.max(x, y);
      	}
      
      	// 取兩數(shù)的較小值
      	public double min(double x, double y) {
      		return Math.min(x, y);
      	}
      
      	// 冪運(yùn)算,即乘方
      	public double pow(double x, double y) {
      		return Math.pow(x, y);
      	}
      
      	// 求方根運(yùn)算,即開方
      	public double sqrt(double x, double y) {
      		double number = x; // 需要求n次方根的數(shù)字
      		double root = x; // 每次迭代后的數(shù)值
      		double n = y; // n次方根的n
      		// 下面利用牛頓迭代法求n次方根
      		for (int i=0; i<5; i  ) {
      			root = (root*(n-1) number/Math.pow(root, n-1))/n;
      		}
      		return root;
      	}
      }

      注意到MathUtil的內(nèi)部方法全部是實(shí)例方法,而非靜態(tài)方法,意味著外部若想調(diào)用這些方法,得先創(chuàng)建MathUtil的實(shí)例才行。比如下面這般:

      		MathUtil math = new MathUtil();

      有了MathUtil類的實(shí)例之后,外部即可通過“math::add”表示相加運(yùn)算的方法引用,通過“math::minus”表示相減運(yùn)算的方法引用了?,F(xiàn)今這種“實(shí)例名稱::方法名稱”的引用形式,正是方法引用的第三個分支——實(shí)例方法引用。下面的運(yùn)算代碼便演示了實(shí)例方法引用的具體用法:

      	// 演示實(shí)例方法的方法引用
      	private static void testInstance() {
      		MathUtil math = new MathUtil();
      		double result;
      		// 雙冒號的方法引用也適用于實(shí)例方法,求兩數(shù)之和
      		result = Arithmetic.calculate(math::add, 3, 2);
      		System.out.println("兩數(shù)之和=" result);
      		// 被引用的方法換成了該實(shí)例的minus方法,求兩數(shù)之差
      		result = Arithmetic.calculate(math::minus, 3, 2);
      		System.out.println("兩數(shù)之差=" result);
      		// 被引用的方法換成了該實(shí)例的multiply方法,求兩數(shù)之積
      		result = Arithmetic.calculate(math::multiply, 3, 2);
      		System.out.println("兩數(shù)之積=" result);
      		// 被引用的方法換成了該實(shí)例的divide方法,求兩數(shù)之商
      		result = Arithmetic.calculate(math::divide, 3, 2);
      		System.out.println("兩數(shù)之商=" result);
      		// 被引用的方法換成了該實(shí)例的remainder方法,求兩數(shù)之余
      		result = Arithmetic.calculate(math::remainder, 3, 2);
      		System.out.println("兩數(shù)之余=" result);
      		// 被引用的方法換成了該實(shí)例的max方法,求兩數(shù)的較大值
      		result = Arithmetic.calculate(math::max, 3, 2);
      		System.out.println("兩數(shù)的較大值=" result);
      		// 被引用的方法換成了該實(shí)例的min方法,求兩數(shù)的較小值
      		result = Arithmetic.calculate(math::min, 3, 2);
      		System.out.println("兩數(shù)的較小值=" result);
      		// 被引用的方法換成了該實(shí)例的pow方法,求某數(shù)的n次方
      		result = Arithmetic.calculate(math::pow, 3, 2);
      		System.out.println("兩數(shù)之乘方=" result);
      		// 被引用的方法換成了該實(shí)例的sqrt方法,求某數(shù)的n次方根
      		result = Arithmetic.calculate(math::sqrt, 3, 2);
      		System.out.println("兩數(shù)之開方=" result);
      	}

      運(yùn)行如上的計(jì)算代碼,可得到下列的計(jì)算結(jié)果日志:

      兩數(shù)之和=5.0
      兩數(shù)之差=1.0
      兩數(shù)之積=6.0
      兩數(shù)之商=1.5
      兩數(shù)之余=1.0
      兩數(shù)的較大值=3.0
      兩數(shù)的較小值=2.0
      兩數(shù)之乘方=9.0
      兩數(shù)之開方=1.7320508075688772

      當(dāng)然了,對于算術(shù)運(yùn)算這茬事,本來就沒有必要非得去創(chuàng)建實(shí)例,完全可以將add、minus、multiply等等諸多方法聲明為靜態(tài)方法,然后外部通過“MathUtil::add”、“MathUtil::minus”、“MathUtil::multiply”來引用對應(yīng)方法。進(jìn)行如此變更的唯一代價,便是把實(shí)例方法引用改成了靜態(tài)方法引用。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多