成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

比較與分析Groovy與Java

開(kāi)發(fā) 后端
本文對(duì)Groovy與java兩者之間的相同之處、不同之處及其聯(lián)系進(jìn)行了總結(jié),希望大家從中有所收獲。

Groovy與Java的比較(上)

1.支持函數(shù)式編程,不需要main函數(shù)

2.默認(rèn)導(dǎo)入常用的包,包括:

java.io

java.math

java.net

java.util

groovy.lang

groovy.util

3.斷言不支持jvm的-ea參數(shù)進(jìn)行開(kāi)關(guān)

4.支持對(duì)對(duì)象進(jìn)行布爾求值

支持對(duì)對(duì)象進(jìn)行布爾求值

5.類不支持default作用域,且默認(rèn)作用域?yàn)閜ublic

6.受檢查類型異常(Checked Exception)也可以不用捕獲

7.一些新的運(yùn)算符

一些新的運(yùn)算符

8.groovy中基本類型也是對(duì)象,可以直接調(diào)用對(duì)象的方法,如:

  1. assert (-12345).abs() == 12345

但浮點(diǎn)運(yùn)算是基于BigDecimal類

  1. assert 0.25 instanceof BigDecimal
  2. assert 0.1 * 3 == 0.3
  3. assert 1.1 + 0.1 == 1.2
  4. assert 1 / 0.25 == 4

Groovy與Java的比較(中)

9.字符串的處理

String對(duì)象和java類似,但沒(méi)有character的概念,沒(méi)有迭代每個(gè)字符的方法。

使用單引號(hào)定義普通字符串,雙引號(hào)定義的字符串可以包含Groovy運(yùn)算符,$符號(hào)則需要轉(zhuǎn)義("\$"),如:

  1. String name = "Ben"
  2. String greeting = "Good morning, ${name}"
  3. assert greeting == 'Good morning, Ben'
  4. String output = "The result of 2 + 2 is: ${2 + 2}"
  5. assert output == "The result of 2 + 2 is: 4"

還可以使用三個(gè)連續(xù)的"來(lái)定義多行字符串,如:

  1. String getEmailBody(String name) {
  2. return """Dear ${name},
  3. Thank you for your recent inquiry. One of our team members
  4. will process it shortly and get back to you. Some time in
  5. the next decade. Probably.
  6. Warmest and best regards,
  7. Customer Services
  8. """
  9. }

char類型的使用方法:

  1. char ch = 'D'
  2. assert ch instanceof Character
  3. String str = "Good morning Ben"
  4. str = str.replace(' ' as char, '+' as char)
  5. assert str == "Good+morning+Ben"

10.as運(yùn)算符,用于沒(méi)有集成關(guān)系的類型間強(qiáng)制類型轉(zhuǎn)換,如:

  1. assert 543667 as String == "543667"
  2. assert 1234.compareTo("34749397" as int) < 0

可通過(guò)實(shí)現(xiàn)asType(Class) 方法來(lái)實(shí)現(xiàn)自定義的as行為,默認(rèn)的方法包括:

默認(rèn)的方法

11.一些集合類型的語(yǔ)法甜頭(Syntax sugar for lists, maps, and ranges)

從語(yǔ)言層面支持List\Map\Range類型,而不是通過(guò)SDK中的類

使用[]創(chuàng)建創(chuàng)建和初始化List、Map,如:

  1. List myList = [ "apple", "orange", "lemon" ]
  2. Map myMap = [ 3: "three", 6: "six", 2: "two" ]
  3. assert 3 == [ 5, 6, 7 ].size()

List\Map支持?jǐn)?shù)組風(fēng)格的用法

  1. List numbers = [ 5, 10, 15, 20, 25 ]
  2. assert numbers[0] == 5 //獲取List中的對(duì)象
  3. assert numbers[3] == 20
  4. assert numbers[-1] == 25 //逆序獲取List對(duì)象
  5. assert numbers[-3] == 15
  6. numbers[2] = 3 //更新List對(duì)象
  7. assert numbers[2] == 3
  8. numbers < < 30 //添加數(shù)據(jù)
  9. assert numbers[5] == 30
  10. Map items = [ "one": "apple",
  11. "two": "orange",
  12. "three": "pear",
  13. "four": "cherry" ]
  14. assert items["two"] == "orange" //從Map中獲得對(duì)象
  15. assert items["four"] == "cherry"
  16. items["one"] = "banana" //更新Map中對(duì)象
  17. assert items["one"] == "banana"
  18. items["five"] = "grape" //增加對(duì)象到中
  19. assert items["five"] == "grape"

新的類型:Range

Range實(shí)現(xiàn)了java.util.List,可以作為L(zhǎng)ist使用,并擴(kuò)展了包含(..)和排除(..< )運(yùn)算符

  1. // an inclusive range
  2. def range = 5..8
  3. assert range.size() == 4
  4. assert range.get(2) == 7
  5. assert range[2] == 7
  6. assert range instanceof java.util.List
  7. assert range.contains(5)
  8. assert range.contains(8)
  9. // lets use an exclusive range
  10. range = 5..< 8
  11. assert range.size() == 3
  12. assert range.get(2) == 7
  13. assert range[2] == 7
  14. assert range instanceof java.util.List
  15. assert range.contains(5)
  16. assert ! range.contains(8)
  17. //get the end points of the range without using indexes
  18. def range = 1..10
  19. assert range.from == 1
  20. assert range.to == 10
  21. List fruit = [
  22. "apple",
  23. "pear",
  24. "lemon",
  25. "orange",
  26. "cherry" ]
  27. for (int i in 0..< fruit.size()) { //Iterates through an exclusive range B
  28. println "Fruit number $i is '${fruit[i]}'"
  29. }
  30. List subList = fruit[1..3] //Extracts a list slice C

12.一些省時(shí)的特性

行末的分號(hào)(;)不是必須的。在沒(méi)有分號(hào)的情況下,groovy計(jì)算一行如果是有效的表達(dá)式,則認(rèn)為下一行是新的表達(dá)式,否則將聯(lián)合下一行共同作為一個(gè)表達(dá)式。分隔多行的表達(dá)式,可以用/符號(hào),如:

  1. String fruit = "orange, apple, pear, " \
  2. + "banana, cherry, nectarine"

方法調(diào)用時(shí)的圓括號(hào)()不是必須的(但建議保留)。但在無(wú)參方法調(diào)用,或第一個(gè)參數(shù)是集合類型定義時(shí)還是必須的:

  1. println "Hello, world!"
  2. println()
  3. println([1, 2, 3, 4])

方法定義中的return語(yǔ)句不是必須的,沒(méi)有return的情況下,將返回方法體中最后一行的值,如下面的方法返回value+1:

int addOne(int value) { value + 1 }

Groovy與Java的比較(下)

13.語(yǔ)言級(jí)別的正則表達(dá)式支持

使用斜線(/)定義正則表達(dá)式,避免java中的多次轉(zhuǎn)義,如"\\\\\\w"相當(dāng)于/\\\w/。

如果要作為java中的Pattern對(duì)象使用,可以使用~符號(hào)表示,如:

  1. assert ~"London" instanceof java.util.regex.Pattern
  2. assert ~/\w+/ instanceof java.util.regex.Pattern

使用=~運(yùn)算符進(jìn)行匹配

  1. assert "Speaking plain English" =~ /plain/

使用==~運(yùn)算符進(jìn)行精確匹配

  1. assert !("Speaking plain English" ==~ /plain/)
  2. assert "Speaking plain English" ==~ /.*plain.*/

捕獲分組,如:

  1. import java.util.regex.Matcher
  2. String str = "The rain in Spain falls mainly on the plain"
  3. Matcher m = str =~ /\b(\w*)ain(\w*)\b/
  4. if (m) {
  5. for (int i in 0..< m.count) {
  6. println "Found: '${m[i][0]}' - " +
  7. "prefix: '${m[i][1]}'" +
  8. ", suffix: '${m[i][2]}'"
  9. }
  10. }

輸出:

  1. Found: 'rain' - prefix: 'r', suffix: ''
  2. Found: 'Spain' - prefix: 'Sp', suffix: ''
  3. Found: 'mainly' - prefix: 'm', suffix: 'ly'
  4. Found: 'plain' - prefix: 'pl', suffix: ''

14.簡(jiǎn)化的javabean

直接使用“.屬性名”的方法代替getter,如:

  1. Date now = new Date()
  2. println "Current time in milliseconds: ${ now.time }"
  3. now.time = 103467843L
  4. assert now.time == 103467843L

屬性定義不需要setter/getter。未指定作用域的屬性,groovy自動(dòng)認(rèn)為是private并生為其成setter/getter,也可以根據(jù)需要進(jìn)行覆寫。如下除了最后一個(gè)字段,都是屬性:

  1. class MyProperties {
  2. static String classVar
  3. final String constant = "constant"
  4. String name
  5. public String publicField
  6. private String privateField
  7. }

簡(jiǎn)化bean的初始化,可以使用Map進(jìn)行初始化,或鍵值對(duì)的方法,如

  1. DateFormat format = new SimpleDateFormat(
  2. lenient: false,
  3. numberFormat: NumberFormat.getIntegerInstance(),
  4. timeZone: TimeZone.getTimeZone("EST"))

可以使用屬性的方式讀取map:

  1. Map values = [ fred: 1, peter: 5, glen: 42 ]
  2. assert values.fred == 1
  3. values.peter = 10
  4. assert values.peter == 10

注:groovy將map的key作為字符串處理,除非是數(shù)字或者用圓括號(hào)包含。這里的fred就是字符串"fred",但引號(hào)不是必須的,只有在key包含空格、句點(diǎn)或其他不能作為Groovy標(biāo)示符的字符存在時(shí)才需要。如果需要使用一個(gè)變量的值作為key,則使用圓括號(hào),如 [ (fred): 1 ]。

15.groovy不具備的java特性

不能用單引號(hào)定義字符類型,但可以使用as運(yùn)算符將一個(gè)字母的字符串轉(zhuǎn)換為字符類型

for循環(huán)中不能用逗號(hào)分隔多個(gè)運(yùn)算符,如下面的代碼是不允許的:

  1. for (int i = 0, j = 0; i < 10; i++, j++) { ... }

不支持DO...WHILE循環(huán),但可以使用while...for運(yùn)算代替

不支持內(nèi)部類和匿名類,但支持閉包和在一個(gè)文件中定義多個(gè)類

16.groovy的重要特性——閉包:

可以看作一個(gè)匿名方法定義,可以賦予給一個(gè)變量名、作為參數(shù)傳遞給方法調(diào)用、或者被方法返回。也可以想象為只有一個(gè)方法定義的匿名類。

閉包的語(yǔ)法{ < arguments> -> < body> },如:

  1. List fruit = [ "apple", "Orange", "Avocado", "pear", "cherry" ]
  2. fruit.sort { String a, String b -> a.compareToIgnoreCase(b) }
  3. println "Sorted fruit: ${fruit}"

注:sort方法只有一個(gè)閉包類型的參數(shù),省略了圓括號(hào);閉包中使用了默認(rèn)的return值

當(dāng)沒(méi)有參數(shù)傳入時(shí),仍然需要保留箭頭的存在{-> ... }

只有一個(gè)參數(shù)傳入時(shí),可以省略箭頭,隱式的創(chuàng)建一個(gè)it參數(shù),引用當(dāng)前對(duì)象,如:

  1. [ "apple", "pear", "cherry" ].each { println it }

可以將閉包賦予一個(gè)變量,如

  1. Closure comparator = { String a, String b ->
  2. a.compareToIgnoreCase(b)
  3. }
  4. List fruit = [ "apple", "Orange", "Avocado", "pear", "cherry" ]
  5. fruit.sort(comparator)
  6. println "Sorted fruit: ${fruit}"
  7. assert comparator("banana", "Lemon") < 0

只有一個(gè)參數(shù)的閉包,可以不傳入?yún)?shù),運(yùn)行時(shí)隱式的傳入null參數(shù)

當(dāng)閉包是一個(gè)方法的最后一個(gè)參數(shù)時(shí),可以寫在圓括號(hào)外面,如:

  1. List list = [ 1, 3, 5, 6 ]
  2. list.inject(0, { runningTotal, value -> runningTotal + value })

可以這樣寫:

  1. assert 15 == list.inject(0) { runningTotal, value -> runningTotal + value }

便于閉包中具有多行時(shí)代碼更加清晰

不要濫用閉包。當(dāng)閉包作為一個(gè)屬性時(shí),不要在子類中覆寫,實(shí)在需要這樣做,使用方法。使用閉包也無(wú)法利用java中很多AOP框架的特性

17.groovy的重要特性——?jiǎng)討B(tài)編程

動(dòng)態(tài)的使用屬性,如下的java代碼:

  1. public void sortPeopleByGivenName(List< Person> personList) {
  2. Collections.sort(personList, new Comparator< Person>() {
  3. public int compare(Person p1, Person p2) {
  4. return p1.getFamilyName().compareTo(p2.getFamilyName());
  5. }
  6. } ) ;
  7. }

可使用下面的代替,當(dāng)需要使用其他字段比較時(shí),不需要修改代碼

  1. def sortPeople(people, property) {
  2. people.sort { p1, p2 -> p1."${property}" < => p2."${property}" }
  3. }

將一個(gè)String作為屬性或方法名進(jìn)行調(diào)用,如:

  1. peopleList.sort()
  2. peopleList."sort"()

動(dòng)態(tài)類型(duck typing:"if it walks like a duck and talks like a duck, it’s probably a duck):運(yùn)行期解析對(duì)象的屬性和方法,允許在運(yùn)行時(shí)增加對(duì)象的屬性和方法而不修改源代碼,因此可能出現(xiàn)調(diào)用未定義方法的情況。

動(dòng)態(tài)編程帶來(lái)的危險(xiǎn):

編譯器不能檢查到類型錯(cuò)誤、方法或?qū)傩缘腻e(cuò)誤調(diào)用,應(yīng)該養(yǎng)成編寫測(cè)試的習(xí)慣

難以調(diào)試,使用“單步跳入(step into)”經(jīng)常進(jìn)入一些反射中,使用“運(yùn)行到光標(biāo)處(run to cursor)”代替

動(dòng)態(tài)的類型定義使代碼難以閱讀,使用良好的命名、注釋,盡量明確定義變量類型,便于IDE檢測(cè)ht potential type errors in the call潛在的錯(cuò)誤。

18.Groovy JDK中的增強(qiáng)

Collection/Array/String具有size()方法

Collection/Array/String具有each(closure)方法,方便的進(jìn)行遍歷

Collection/Array/String具有find(closure)、findAll(closure)方法,find返回第一個(gè)符合條件的對(duì)象,findAll返回所有符合條件對(duì)象列表,如:

  1. def glen = personList.find { it.firstName == "Glen" }

Collection/Array/String具有collect(closure)方法,對(duì)集合中每個(gè)對(duì)象執(zhí)行一段方法后,返回結(jié)果集,如:

  1. def names = [ "Glen", "Peter", "Alice", "Graham", "Fiona" ]
  2. assert [ 4, 5, 5, 6, 5 ] == names.collect { it.size() }

Collection/Array/String具有sort(closure)方法,包括:

一個(gè)參數(shù)的閉包,如:

  1. def names = [ "Glen", "Peter", "Ann", "Graham", "Veronica" ]
  2. def sortedNames = names.sort { it.size() }
  3. assert [ "Ann", "Glen", "Peter", "Graham", "Veronica" ] == sortedNames

兩個(gè)參數(shù)的閉包,如:

  1. def names = [ "Glen", "Peter", "Ann", "Graham", "Veronica" ]
  2. def sortedNames = names.sort { name1, name2 ->
  3. name1.size() < => name2.size()
  4. }
  5. assert [ "Ann", "Glen", "Peter", "Graham", "Veronica" ] == sortedNames

Collection/Array具有join(String)方法

  1. def names = [ "Glen", "Peter", "Alice", "Fiona" ]
  2. assert "Glen, Peter, Alice, Fiona" == names.join(", ")

File.text屬性讀取文件內(nèi)容作為字符串返回

File.size()方法返回文件的byte值,相當(dāng)于File.length()方法

File.withWriter(closure)方法,從文件創(chuàng)建一個(gè)Writer對(duì)象傳給閉包,閉包執(zhí)行完畢后,依賴的輸出流自動(dòng)安全關(guān)閉。另外還有若干with...方法查看文檔

Matcher.count返回相應(yīng)Matcher的匹配數(shù)量

Number.abs()方法,對(duì)數(shù)字求絕對(duì)值

Number.times(closure)執(zhí)行n次閉包,將當(dāng)前執(zhí)行的次數(shù)作為參數(shù)傳給閉包

19.XML的處理

示例的XML:

  1. < root>
  2. < item qty="10">
  3. < name>Orange< /name>
  4. < type>Fruit< /type>
  5. < /item>
  6. < item qty="6">
  7. < name>Apple< /name>
  8. < type>Fruit< /type>
  9. < /item>
  10. < item qty="2">
  11. < name>Chair< /name>
  12. < type>Furniture< /type>
  13. < /item>
  14. < /root>

處理程序

  1. import groovy.xml.MarkupBuilder
  2. import groovy.util.XmlSlurper
  3. def file = new File("test.xml")
  4. def objs = [
  5. [ quantity: 10, name: "Orange", type: "Fruit" ],
  6. [ quantity: 6, name: "Apple", type: "Fruit" ],
  7. [ quantity: 2, name: "Chair", type: "Furniture" ] ]
  8. def b = new MarkupBuilder(new FileWriter(file)) 創(chuàng)建MarkupBuilder對(duì)象
  9. b.root {
  10. 動(dòng)態(tài)調(diào)用root方法,但builder對(duì)象并沒(méi)有該方法,把它作為一個(gè)新的XML對(duì)象的根節(jié)點(diǎn),并且把方法名作為根節(jié)點(diǎn)名稱
  11. objs.each { o ->
  12. item(qty: o.quantity) {
  13. name(o.name)
  14. type(o.type)
  15. }
  16. }
  17. }
  18. 遍歷集合,創(chuàng)建節(jié)點(diǎn),其中item/name/type也是動(dòng)態(tài)的方法,以方法名作為節(jié)點(diǎn)名,方法參數(shù)作為節(jié)點(diǎn)的屬性
  19. def xml = new XmlSlurper().parse(file)
  20. 使用XmlSlurper對(duì)象解析內(nèi)存中的XML文件
  21. assert xml.item.size() == 3
  22. assert xml.item[0].name == "Orange"
  23. assert xml.item[0].@qty == "10"
  24. 使用動(dòng)態(tài)的屬性名讀取XML節(jié)點(diǎn)
  25. 使用@字符讀取節(jié)點(diǎn)屬性
  26. println "Fruits: ${xml.item.findAll {it.type == 'Fruit'}*.name }"
  27. println "Total: ${xml.item.@qty.list().sum {it.toInteger()} }"

20.最佳實(shí)踐

使用地道的Groovy語(yǔ)法:盡可能使用groovy中簡(jiǎn)化后的語(yǔ)法風(fēng)格,減少代碼量

實(shí)驗(yàn):使用groovy console或shell可以方便的實(shí)驗(yàn)groovy代碼

盡可能使用方法,而不是閉包。方法易于理解,也利于和java交互

在方法簽名中盡可能的使用確定的類型,便于代碼閱讀和IDE的錯(cuò)誤檢測(cè)。在使用動(dòng)態(tài)類型時(shí)要有清晰完善的文檔注釋

【編輯推薦】

  1. 多核時(shí)代考驗(yàn)Java代碼編寫習(xí)慣
  2. JSR通過(guò)JavaEE 6依賴注入標(biāo)準(zhǔn) 各方觀點(diǎn)不一
  3. Sun發(fā)布JDK 7早期預(yù)覽版 JVM性能大幅提升
  4. 來(lái)自一年前的預(yù)測(cè):Java平臺(tái)與死亡相去甚遠(yuǎn)
  5. Java新型垃圾回收器G1深入探索
責(zé)任編輯:book05 來(lái)源: popoer
相關(guān)推薦

2012-07-02 14:47:38

HTML5

2017-04-27 10:38:28

排序算法比較分析

2009-08-03 10:44:51

Groovy 1.7Groovy

2013-12-10 23:06:58

開(kāi)源云平臺(tái)云計(jì)算

2012-10-11 10:51:39

開(kāi)源IaaS云

2011-09-22 13:49:44

XML基準(zhǔn)測(cè)試

2018-11-01 09:14:42

CNNRNN神經(jīng)網(wǎng)絡(luò)

2017-03-07 09:05:05

JavaScriptJavaPHP

2009-07-07 17:23:08

Java Servle

2023-01-10 08:04:31

2010-07-14 10:15:31

2009-09-14 18:39:41

MCSE與CCNA

2010-05-12 11:24:16

2020-08-11 10:05:16

Qlik SenseTableau數(shù)據(jù)分析

2023-02-07 09:17:19

Java注解原理

2010-08-23 14:44:06

思科

2009-08-07 10:27:45

Eclipse和Net

2010-03-11 10:51:19

Python編程語(yǔ)言

2009-07-14 16:30:41

Swing與SWT

2009-07-03 12:48:24

Java Servle
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日韩欧美在线不卡 | 久久伊人久久 | 九九热在线精品视频 | 中文字幕第一页在线 | 国产日韩精品久久 | 97精品国产一区二区三区 | 亚洲精品中文字幕中文字幕 | 国产国产精品久久久久 | 精品中文字幕一区二区 | 国产成人在线看 | 亚洲综合三区 | 亚洲精品1区 | 国产天天操| 久久99精品久久久久久狂牛 | 精品一区二区三区在线观看 | 久久只有精品 | 在线看中文字幕 | 男女视频在线免费观看 | a在线视频 | 日韩综合网 | 男人的天堂在线视频 | 女生羞羞网站 | 国产亚洲精品综合一区 | 久久精品一区二区视频 | 国产日韩欧美一区二区在线播放 | 欧美精品v | 黄色大全免费看 | 水蜜桃亚洲一二三四在线 | 亚洲第一天堂 | 国产区精品在线观看 | 国产精品毛片av | 国产精品久久av | 福利视频网址 | 日韩精品一区二区三区在线观看 | 正在播放一区二区 | 亚洲黄色成人网 | 九九久久久 | 欧美毛片免费观看 | 91精品国产91久久久久久最新 | 色婷婷激情综合 | 亚洲一区二区中文字幕 |