日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
比較與分析Groovy與Java

Groovy與Java的比較(上)

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、重慶小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了新縣免費(fèi)建站歡迎大家使用!

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)行開關(guān)

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

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

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

7.一些新的運(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類似,但沒有character的概念,沒有迭代每個(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)算符,用于沒有集成關(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)的方法包括:

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)(;)不是必須的。在沒有分號(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ǔ)句不是必須的,沒有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)沒有參數(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ì)象并沒有該方法,把它作為一個(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í)要有清晰完善的文檔注釋


網(wǎng)站欄目:比較與分析Groovy與Java
本文路徑:http://www.5511xx.com/article/cdsedij.html