1、无处不在对象
1.1、java的类型系统:原生类型和引用类型
- java原生类型没有包装类对应的方法
- groovy基本数据类型是有包装类的方法
1.2、Groovy则是万物皆对象
1.3、自动拆箱和装箱
1.4、没有中间状态的拆箱
2、可选类型概念
2.1、赋值类型
- def
2.2、动态groovy 是类型安全
2.3、转换工作
-
[] 就是调用构造方法
-
import java.awt.Point import java.awt.Rectangle /** * @author liangchen* @date 2020/10/23 */ class CastingDemo { static void main(String[] args) { // 典型模式 Point topleft = new Point(0, 0) // List 转换 Point botRight = [100,100] // Map cast Point center = [x:50, y:50] assert botRight instanceof Point assert center instanceof Point def rect = new Rectangle() // [] 相当于调用构造方法 rect.location = [0, 0] // Dimension rect.size = [width:100, height:100] } }
3.2.4、转可选类型
3、重写操作
3.1、 预览重写操作符
3.2、重写操作实战
-
@Imutable 只能通过Plus进行操作
-
class OverridingDemo { static void main(String[] args) { Money buck = new Money(1, "USD") assert buck assert buck == new Money(1,'USD') assert buck + buck == new Money(2, 'USD') assert buck + 1 == new Money(2, 'USD') } } @Immutable class Money { int amount String currency Money plus (Money other){ if(null == other) return this if (other.currency != currency) { throw new IllegalArgumentException("cannot add $other.currency to $currency") } return new Money(amount + other.amount, currency) } Money plus (Integer more){ return new Money(amount + more, currency) } }
4、字符串操作
4.1、字符串变量
- $变量, 都是交给GString 处理 必须使用双引号
4.2、GString运作
-
字符串使用
-
class GStringDemo { static void main(String[] args) { // $变量名,注意需要双引号引起来 def me = 'Tarzan' def you = 'Jane' def line = "me $me - you $you" assert line == 'me Tarzan - you Jane' TimeZone.default = TimeZone.getTimeZone("GMT") def date = new Date(0) def dateMap = [y:date[Calendar.YEAR] - 1900, m:date[Calendar.MONTH], d:date[Calendar.DAY_OF_MONTH]] def out = "Year $dateMap.y Month $dateMap.m Day $dateMap.d" assert out == 'Year 70 Month 0 Day 1' def tz=TimeZone.getTimeZone('GMT') def format = 'd MMM YYYY HH:mm:SS z' out = "Date is ${date.format(format, tz)} !" assert out == 'Date is 1 一月 1970 00:00:00 GMT !' // 多行字符串 def sql = """ SELECT FROM MyTable WHERE Year = $dateMap.y """ assert sql == """ SELECT FROM MyTable WHERE Year = 70 """ out = "my 0.02\$" assert out == 'my 0.02$' } }
4.3、从java到Groovy
4.4、GString 操作
class JavaToGroovy {
static void main(String[] args) {
// java
System.out.print("Hello Groovy")
// 简化groovy 采用单引号
System.out.print('Hello Groovy')
// 继续简化
print ('Hello Groovy')
//继续简化
print 'Hello Groovy'
String greeting = 'Hello Groovy'
assert greeting.startsWith('Hello')
assert greeting.getAt(0) =='H'
assert greeting[0] == 'H'
assert greeting.indexOf('Groovy') >=0
assert greeting.contains('Groovy')
assert greeting[6..11] == 'Groovy'
// 居然支持减法
assert 'Hi' + greeting - 'Hello' == 'Hi Groovy'
// 计数 o字符的次数
assert greeting.count('o') == 3
// 左边补足3位(空格)
assert 'x'.padLeft(3) == ' x'
// 右边补足3 (_)
assert 'x'.padRight(3,'_') == 'x__'
//中间两侧补足3位
assert 'x'.center(3) == ' x '
// 多个x累加
assert 'x' * 3 =='xxx'
// StringBuffer 操作
def greet = 'Hello'
// 变成StringBuffer类型
greet <<= ' Groovy'
println greet
assert greet instanceof java.lang.StringBuffer
// 执行拼接操作
greet << '!'
assert greet.toString() == 'Hello Groovy!'
greet[1..4] = 'i'
assert greet.toString() == 'Hi Groovy!'
}
}
5、正则表达式操作
5.1、具体字符匹配
-
class RegularGStringDemo { static void main(String[] args) { // 以/开头和结尾, /pattern/ assert "abc" == /abc/ assert "\\d" == /\d/ def reference = 'hello' assert reference == /$reference/ } }
-
符号 含义 ^ 一行开始 $ 一行结尾 \d 数字 \D 非数字 \s 空格 \S 非空格 \w 字符 \W 非字符 \b 单词边界 () 组 (x|y) x 或 y, 例如(Groovy|Java|Python) \ \1 反向匹配组中第一个 x* 0或多个x x+ 1或多个 x? 0或一个 x{m,n} 至少m个,至多n个 x{m} m个x [a-f] 字符 abcdef [^a] 不是以a开头 (?is:x) switch模式如果是值是x, i忽略大小写,s意味单行模式
5.2、应用模式
-
/** * 正则表达式 示例 * @author liangchen* @date 2020/10/24 */ class RegularExpressionDemo { static void main(String[] args) { def twister = 'she sells sea shells at the sea shore of seychelles' // twister 找到 以s开头, a结尾 assert twister =~ /s.a/ def finder = (twister =~ /s.a/) assert finder instanceof java.util.regex.Matcher // 单词,中间空格隔开 assert twister ==~ /(\w+ \w+)*/ def WORD = /\w+/ def matches = (twister ==~ /($WORD $WORD)*/) assert matches instanceof java.lang.Boolean // 未匹配 assert !(twister ==~ /s.e/) //匹配替换单词成x def wordsByX = twister.replaceAll(WORD,'x') assert wordsByX == 'x x x x x x x x x x' // 空格切割 def words = twister.split(/ /) assert words.size() == 10 assert words[0] == 'she' } }
5.3、 模式实战( match)
-
class RegularEachMatch { static void main(String[] args) { def myFairStringy = 'The rain in Spain stays mainly in the plain!' // 以ain结尾 \b 是单词边界 def wordEnding = /\w*ain/ def rhyme = /\b$wordEnding\b/ // 找出所有匹配表达式字符串 def found = '' myFairStringy.eachMatch(rhyme) { match -> found += match+' ' } assert found == 'rain Spain plain ' // 找出所有匹配表达式 found = '' (myFairStringy =~rhyme).each(match -> found +=match + ' ') assert found == 'rain Spain plain ' // 替换 单个字符it -> it-'ain'+'__' , 去掉'ain' 加上__ def cloze = myFairStringy.replaceAll(rhyme){ it-'ain'+'__' } assert cloze == 'The r__ in Sp__ stays mainly in the pl__!' // 取出部分数据 def matcher = 'a b c' =~ /\S/ assert matcher[0] == 'a' assert matcher[1..2] == ['b','c'] assert matcher.size() == 3 def (a,b) = 'a b' =~ /\S/ assert a =='a' assert b =='b' // 匹配map def matchMap = 'a:1 b:2 c:3' =~ /(\S+):(\S+)/ assert matchMap.hasGroup() // 匹配第一条数据 assert matchMap[0] == ['a:1', 'a', '1'] // 第二匹配, 第2个组 assert matchMap[1][2] == '2' matchMap.each {full, key, value -> assert full.size() == 3 // a,b,c assert key.size() ==1 println key // 1,2,3 assert value.size() == 1 println( value) } } }
5.4、模式和性能
-
执行效率
-
/** * 正则表达式执行效率 示例 * @author liangchen* @date 2020/10/24 */ class RegularPatternReuseDemo { static void main(String[] args) { def twister = 'she sells sea shells at the sea shore of seychelles' def regex =/\b(\w)\w*\1\b/ def many = 100 * 1000 // 隐模式匹配 比 显示慢 3-5倍 def start =System.nanoTime() many.times { // 贪婪模式 twister =~ regex } def timeImplicit = System.nanoTime() - start start = System.nanoTime() // 显示模式匹配 def pattern = ~regex many.times { pattern.matcher(twister) } def timePredef = System.nanoTime() - start assert timeImplicit > timePredef * 2 } }
5.5、 Pattern 分类
-
/** * 匹配特有的方法,先定义pattern,后匹配实际数据 * @author liangchen* @date 2020/10/24 */ class PatternClassificationDemo { static void main(String[] args) { def fourLetters = ~/\w{4}/ // isCase 是否满足,四个字符要求 assert fourLetters.isCase('work') // in 是否满足要求 ,四个字符 assert 'love' in fourLetters switch ('beer') { case fourLetters: assert true; break default: assert false } // grep 查找四个字符数组内容 def beats =['bear','wolf','tiger', 'regex'] assert beats.grep(fourLetters) == ['bear', 'wolf'] } }
6、数字类型操作
-
数字表达式示例
-
表达式 结果类型 描述 1f*2f Double 在java将是FLoat (Byte)1 +(Byte)2 Integer 1*2L Long 1/2 BigDecimal(0.5) 在java将是0, (int)(1/2) Integer(0) BigDecimal to Integer 1.intdiv(2) Integer(0) 等同java的1/2 Integer.MAX_VALUE+1 Integer Non 2**30 Integer 2**31 BigInteger 2**3.5 Double 2G+1G BigInteger 2.5G +1G BigDecimal 1.5G == 1.5F Boolean(true) 转换成BigDecimal进行比较 1.1G==1.1F Boolean(false) 1.1F转成BigDecimal不是1.1G
6.2、GDK的数字方法
-
class NumberDemo { static void main(String[] args) { assert 1 == (-1).abs() assert 2 == 2.5.toInteger() assert 2 == 2.5 as Integer assert 2 == (int) 2.5 assert 3== 2.5f.round() assert 3.142 == Math.PI.round(3) assert 4 == 4.5f.trunc() assert 2.718 == Math.E.trunc(3) assert '2.718'.isNumber() assert 5 == '5'.toInteger() assert 5 == '5' as Integer // char 代表数字 assert 53 == (int) '5' assert '6 times' == 6 + ' times' // 步长 def store ='' 10.times { store += 'x' } assert store == 'xxxxxxxxxx' store ='' 1.upto(5) { number -> store += number } assert store == '12345' store = '' 2.downto(-2) { number -> store += number +' ' } assert store == '2 1 0 -1 -2 ' store = '' 0.step(0.5,0.1){ number -> store += number +' ' } assert store == '0 0.1 0.2 0.3 0.4 ' } }
7、总结
- 简单数据类型
- 正则表达式