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

比較與分析Groovy與Java

開發 后端
本文對Groovy與java兩者之間的相同之處、不同之處及其聯系進行了總結,希望大家從中有所收獲。

Groovy與Java的比較(上)

1.支持函數式編程,不需要main函數

2.默認導入常用的包,包括:

java.io

java.math

java.net

java.util

groovy.lang

groovy.util

3.斷言不支持jvm的-ea參數進行開關

4.支持對對象進行布爾求值

支持對對象進行布爾求值

5.類不支持default作用域,且默認作用域為public

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

7.一些新的運算符

一些新的運算符

8.groovy中基本類型也是對象,可以直接調用對象的方法,如:

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

但浮點運算是基于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對象和java類似,但沒有character的概念,沒有迭代每個字符的方法。

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

  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"

還可以使用三個連續的"來定義多行字符串,如:

  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運算符,用于沒有集成關系的類型間強制類型轉換,如:

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

可通過實現asType(Class) 方法來實現自定義的as行為,默認的方法包括:

默認的方法

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

從語言層面支持List\Map\Range類型,而不是通過SDK中的類

使用[]創建創建和初始化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支持數組風格的用法

  1. List numbers = [ 5, 10, 15, 20, 25 ]
  2. assert numbers[0] == 5 //獲取List中的對象
  3. assert numbers[3] == 20
  4. assert numbers[-1] == 25 //逆序獲取List對象
  5. assert numbers[-3] == 15
  6. numbers[2] = 3 //更新List對象
  7. assert numbers[2] == 3
  8. numbers < < 30 //添加數據
  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中獲得對象
  15. assert items["four"] == "cherry"
  16. items["one"] = "banana" //更新Map中對象
  17. assert items["one"] == "banana"
  18. items["five"] = "grape" //增加對象到中
  19. assert items["five"] == "grape"

新的類型:Range

Range實現了java.util.List,可以作為List使用,并擴展了包含(..)和排除(..< )運算符

  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.一些省時的特性

行末的分號(;)不是必須的。在沒有分號的情況下,groovy計算一行如果是有效的表達式,則認為下一行是新的表達式,否則將聯合下一行共同作為一個表達式。分隔多行的表達式,可以用/符號,如:

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

方法調用時的圓括號()不是必須的(但建議保留)。但在無參方法調用,或第一個參數是集合類型定義時還是必須的:

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

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

int addOne(int value) { value + 1 }

Groovy與Java的比較(下)

13.語言級別的正則表達式支持

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

如果要作為java中的Pattern對象使用,可以使用~符號表示,如:

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

使用=~運算符進行匹配

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

使用==~運算符進行精確匹配

  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.簡化的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自動認為是private并生為其成setter/getter,也可以根據需要進行覆寫。如下除了最后一個字段,都是屬性:

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

簡化bean的初始化,可以使用Map進行初始化,或鍵值對的方法,如

  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作為字符串處理,除非是數字或者用圓括號包含。這里的fred就是字符串"fred",但引號不是必須的,只有在key包含空格、句點或其他不能作為Groovy標示符的字符存在時才需要。如果需要使用一個變量的值作為key,則使用圓括號,如 [ (fred): 1 ]。

15.groovy不具備的java特性

不能用單引號定義字符類型,但可以使用as運算符將一個字母的字符串轉換為字符類型

for循環中不能用逗號分隔多個運算符,如下面的代碼是不允許的:

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

不支持DO...WHILE循環,但可以使用while...for運算代替

不支持內部類和匿名類,但支持閉包和在一個文件中定義多個類

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

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

閉包的語法{ < 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方法只有一個閉包類型的參數,省略了圓括號;閉包中使用了默認的return值

當沒有參數傳入時,仍然需要保留箭頭的存在{-> ... }

只有一個參數傳入時,可以省略箭頭,隱式的創建一個it參數,引用當前對象,如:

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

可以將閉包賦予一個變量,如

  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

只有一個參數的閉包,可以不傳入參數,運行時隱式的傳入null參數

當閉包是一個方法的最后一個參數時,可以寫在圓括號外面,如:

  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 }

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

不要濫用閉包。當閉包作為一個屬性時,不要在子類中覆寫,實在需要這樣做,使用方法。使用閉包也無法利用java中很多AOP框架的特性

17.groovy的重要特性——動態編程

動態的使用屬性,如下的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. }

可使用下面的代替,當需要使用其他字段比較時,不需要修改代碼

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

將一個String作為屬性或方法名進行調用,如:

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

動態類型(duck typing:"if it walks like a duck and talks like a duck, it’s probably a duck):運行期解析對象的屬性和方法,允許在運行時增加對象的屬性和方法而不修改源代碼,因此可能出現調用未定義方法的情況。

動態編程帶來的危險:

編譯器不能檢查到類型錯誤、方法或屬性的錯誤調用,應該養成編寫測試的習慣

難以調試,使用“單步跳入(step into)”經常進入一些反射中,使用“運行到光標處(run to cursor)”代替

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

18.Groovy JDK中的增強

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

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

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

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

Collection/Array/String具有collect(closure)方法,對集合中每個對象執行一段方法后,返回結果集,如:

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

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

一個參數的閉包,如:

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

兩個參數的閉包,如:

  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屬性讀取文件內容作為字符串返回

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

File.withWriter(closure)方法,從文件創建一個Writer對象傳給閉包,閉包執行完畢后,依賴的輸出流自動安全關閉。另外還有若干with...方法查看文檔

Matcher.count返回相應Matcher的匹配數量

Number.abs()方法,對數字求絕對值

Number.times(closure)執行n次閉包,將當前執行的次數作為參數傳給閉包

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)) 創建MarkupBuilder對象
  9. b.root {
  10. 動態調用root方法,但builder對象并沒有該方法,把它作為一個新的XML對象的根節點,并且把方法名作為根節點名稱
  11. objs.each { o ->
  12. item(qty: o.quantity) {
  13. name(o.name)
  14. type(o.type)
  15. }
  16. }
  17. }
  18. 遍歷集合,創建節點,其中item/name/type也是動態的方法,以方法名作為節點名,方法參數作為節點的屬性
  19. def xml = new XmlSlurper().parse(file)
  20. 使用XmlSlurper對象解析內存中的XML文件
  21. assert xml.item.size() == 3
  22. assert xml.item[0].name == "Orange"
  23. assert xml.item[0].@qty == "10"
  24. 使用動態的屬性名讀取XML節點
  25. 使用@字符讀取節點屬性
  26. println "Fruits: ${xml.item.findAll {it.type == 'Fruit'}*.name }"
  27. println "Total: ${xml.item.@qty.list().sum {it.toInteger()} }"

20.最佳實踐

使用地道的Groovy語法:盡可能使用groovy中簡化后的語法風格,減少代碼量

實驗:使用groovy console或shell可以方便的實驗groovy代碼

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

在方法簽名中盡可能的使用確定的類型,便于代碼閱讀和IDE的錯誤檢測。在使用動態類型時要有清晰完善的文檔注釋

【編輯推薦】

  1. 多核時代考驗Java代碼編寫習慣
  2. JSR通過JavaEE 6依賴注入標準 各方觀點不一
  3. Sun發布JDK 7早期預覽版 JVM性能大幅提升
  4. 來自一年前的預測:Java平臺與死亡相去甚遠
  5. Java新型垃圾回收器G1深入探索
責任編輯:book05 來源: popoer
相關推薦

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

開源云平臺云計算

2012-10-11 10:51:39

開源IaaS云

2011-09-22 13:49:44

XML基準測試

2017-03-07 09:05:05

JavaScriptJavaPHP

2009-07-07 17:23:08

Java Servle

2018-11-01 09:14:42

CNNRNN神經網絡

2010-07-14 10:15:31

2023-01-10 08:04:31

2009-09-14 18:39:41

MCSE與CCNA

2010-05-12 11:24:16

2020-08-11 10:05:16

Qlik SenseTableau數據分析

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編程語言

2009-07-14 16:30:41

Swing與SWT

2009-07-03 12:48:24

Java Servle
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 操一草| 盗摄精品av一区二区三区 | 精品久久久网站 | 一区视频在线 | 99色在线 | 欧美日韩网站 | 91国内精精品久久久久久婷婷 | 国产精品二区三区在线观看 | 精品无码久久久久久国产 | 亚洲一区二区三区桃乃木香奈 | 国产精品国产成人国产三级 | 91成人在线视频 | 亚洲精品免费观看 | 欧洲精品在线观看 | 精品在线一区二区 | 精品国产不卡一区二区三区 | 中文字幕国产一区 | 看片国产 | 久久久久网站 | 91免费在线视频 | 午夜精品影院 | 成人在线观看免费 | 91视频三区 | 福利视频网站 | 人人干免费 | 精品麻豆剧传媒av国产九九九 | 国产探花在线精品一区二区 | 视频在线一区二区 | 亚洲一区视频在线 | 国产精品99久久久久久久vr | 国产精品国产三级国产aⅴ原创 | 日韩欧美视频 | 日韩欧美在线视频 | 美女视频一区 | 欧美一区二区三区在线 | 久久99精品国产99久久6男男 | 久久精品亚洲精品国产欧美 | 操久久 | 黄色一级免费 | 91精品麻豆日日躁夜夜躁 | 天堂av中文在线 |