Groovy and Grails Recipes翻译之旅——Groovy数据类型和控制结构(1)

 

3.1.           Groovy中存在几种strings,如何使用?

Groovy支持两种类型字符串:一般的Java字符串,它是java.lang.String的实例;和GStrings,它是groovy.lang.GString的实例,并且允许文本中包含占位符。GStrings并不是String的子类,因为String类是最终类(final class)不能被继承。然而,GString与一般的字符串一样,因为Groovy能将GStrings转型为Java strings

GString 适用于编写模板代码(templating),因为您必须动态构建字符串(GStrings are useful in templating situations where you have to build your string dynamicly)。清单3.1给出了一个例子。

 

清单3.1 使用GStrings

 

firstWord = 'Hello'

secondWord = 'dlroW'

println  "$firstWord ${secondWord.reverse()}"

 

 

结果如下:

Hello World

 

GStrings不同于Java strings在于它们允许以${..}的语法嵌入变量。如果一个字符串由双引号或三重引号括起来,并且包含一个非转义符(unescaped$,它必定是groovy.lang.GString的一个实例;否则,就是java.lang.String的一个实例。

${..}里可以包含任意有效的Groovy表达式,包括方法调用或变量名。只有调用GStringtoString方法时(例如,把结果输出到控制台),${..}表达式才被求值。

Groovy支持的另一种字符串便是java.lang.String。然而,GDK还是动态注入许多帮助方法,使其易于应用。

以下的例子展示了在Groovy中声明一个字符串的不同方式:

 

s1 = "Hello \"World\" " //Escape double quotes,转义双引号

s2 = 'Hello "World" '

assert s1 == s2

s3 = 'Hello \'World\' ' //Escape single quotes,转义单引号

s4 = "Hello 'World' "

assert s3 == s4

assert new String('Hello World') == "Hello World"

def s = ['h','e','l','l','o'] as char[]

assert new String(s) == 'hello'

assert new String(s,0,4) == 'hell'

s.eachWithIndex{ch,index -> assert ch == s[index]}

assert 'hello'.toCharArray() == ['h','e','l','l','o']

 

常用的转义符:

assert '\t' == '\011'    //TabTab

assert '\n' == '\012'    //New line,换行符

assert '\r' == '\015'    //Carriage return,回车

assert '\n' == """

""" //Spanning multiple lines,跨越多行

 

对象的字符串表示:

def object = new Object()

assert String.valueOf(object) == object.toString() //Objects

assert String.valueOf(true) == true.toString() //Booleans

assert String.valueOf('a') == 'a'.toString() //Characters

assert String.valueOf(1) == 1.toString() //Numbers

assert String.valueOf([a:1,b:2]) == [a:1,b:2].toString() //Collections

 

字符串长度:

 

s = "Hello World"

assert s.size() == 11

assert s.size() == s.length()

 

填充(pad)字符串:

 

assert 'Hello'.padRight(7,'*') == 'Hello**'

assert 'Hello'.padLeft(7,'*') == '**Hello'

assert 'Hello'.center(9,'*') == '**Hello**'

 

分解字符串:

s = "The quick brown fox jumps over the lazy dog"

assert s.tokenize() == ['The','quick','brown','fox','jumps','over','the','lazy','dog']

assert s.tokenize() == new StringTokenizer(s).collect{it}

s1 = "The,quick*brown*fox,*jumps*over*the*lazy*dog"

assert s1.tokenize(',*') == s.tokenize()

 

查询字符串:

 

alphabets = new String('a' .. 'z' as char[])

assert alphabets.find{it > 'f'} == 'g' //First one found

assert alphabets.findAll{it > 'f'} == 'g' .. 'z'//ALl found

assert alphabets.findIndexOf{ it > 'f'} == alphabets.indexOf('g')

assert alphabets.every {it > 'A'}

assert alphabets.any{it < 'c'}

assert alphabets.startsWith('abc')

assert alphabets.endsWith('xyz')

assert alphabets.contains('def')

assert alphabets.indexOf('c') == 2

assert alphabets.indexOf('d') == alphabets.lastIndexOf('d')

assert alphabets.count('a') == 1

 

替换字符串:

 

s = "Hello"

assert s.replace('H','Y') == 'Yello'

assert s.replace('l','p') == 'Heppo'

 

字符串反转:

 

s = 'mirror'

assert s.reverse() == 'rorrim'

 

字符串操作符:

 

assert 'hello' + ' world' - 'l' == 'helo world' //Subtracts at most one l

assert ('Today is Sunday' - 'Sunday').trim() == 'Today is'

assert 'hello ' * 2 == 'hello hello '

def empty = []

assert 'abc'.each{empty << it} == 'abc'

assert 'abc'.next() == 'abd'

assert 'abc'.previous() == 'abb'

 

下标操作符:

 

assert 'hello'[1] == 'e'

assert 'hello'[2..'hello'.size() - 1] == 'llo'

assert 'hello'[0,2,4] == 'hlo'

assert 'hello'[-4,-2] == 'el'

 

字符串比较:

 

assert 'a' < 'b'

assert 'a' > 'A'

assert 'a'.compareTo('b') == -1

assert 'a'.compareToIgnoreCase('A') == 0

 

寻找最大值和最小值:

 

Collections.max('abcdeF'.toList()) == 'e'

assert Collections.max('abcdeF'.toList(), String.CASE_INSENSITIVE_ORDER) == 'F'

assert Collections.min(['abc','abd','abe']) == 'abc'   

assert Collections.min(['Abc','aBd','abE'], String.CASE_INSENSITIVE_ORDER) == 'Abc'

 

StringBuffersStringBuilders是可变的,允许字符串改变。StringBuilder不是线程安全的,因此处理速度要比StringBuffers快。

 

def sb = new StringBuffer('Hello World')

assert sb.toString() == 'Hello World'

sb.length = 5

assert sb.toString() == 'Hello'

assert sb.substring(0,2) == 'He'

//Use <<, append(String) or leftShift(String) to append to a StringBuffer.

//Using + to append to a StringBuffer will return a String

sb = new StringBuffer("Hello")

assert sb + ' World' in java.lang.String

assert sb << ' World' in java.lang.StringBuffer

assert sb.toString() == ("Hello World")

assert sb.append(", Groovy rocks").toString() == "Hello World, Groovy rocks"

assert sb.leftShift(". Doesn't?").toString() == "Hello World, Groovy rocks. Doesn't?"

 

您也可以对StringBufferStringBuilder使用下标,如:

 

sb = new StringBuffer("abcdefg")

assert sb[0] == 'a'

assert sb[2..4] == 'cde'

assert sb[0].class == String

assert sb[-6..-4] == "bcd"

sb[0..2] = "xyz"

assert sb.toString() == "xyzdefg"

 

操作StringBuffers

 

sb = new StringBuffer("StringBuffers are mutable")

sb.delete(sb.indexOf(" are mutable"),sb.size())

assert sb.toString() == "StringBuffers"

sb.insert(sb.size(), " are mutable")

assert sb.toString() == "StringBuffers are mutable"

sb.replace(sb.indexOf("StringBuffers"), "StringBuffers".size(), "StringBuilders")

assert sb.toString() == "StringBuilders are mutable"

def string = new String(sb)

def string2 = string.replaceAll("StringBuilders", "StringBuffers")

assert string2 == "StringBuffers are mutable"

 

正如您看到的,GDKjava.lang.Stringjava.lang.StringBufferjava.lang.StringBuilder基础上添加了很多实用的方法。前面的例子只讨论部分方法,因此推荐您查看StringAPI文档,http://groovy.codehaus.org/groovy-jdk/java/lang/String.htmlStringBuffer, http://groovy.codehaus.org/groovy-jdk/java/lang/StringBuffer.html; StringBuilder, http://groovy.codehaus.org/groovy-jdk/java/lang/StringBuilder.html

Groovy中使用字符串时,需要注意以下几点:

l  Java一样,Groovy中的字符串也是不可变的(即只读的)。欲改变字符串值需使用StringBufferStringBuilder

l  Groovy中,如果字符串如果由单引号括起来,或者由双引号或三重引号括起来但没有非转义的美元符号($),那么该字符串是java.lang.String的一个实例。您可使用JDK中任意字符串方法。另外,GDK动态注入额外的实用方法到String类。

l  由于Groovy会自动转型为String类,您可以在任何时候使用GStrings

l  字符串可被单引号,双引号或者三重引号括起来。其中,三重引号可直接跨越数行并且输出中仍包含回车符、制表符和空格符。

l  Groovy使用size方法来查询一个字符串,StringBufferStringBuilder的长度,与查询一个集合的长度相统一。

l  某些字符串方法接受闭包,它明确说明需要满足的条件,例如,findfindAllfindIndexOfeveryany。这些方法都是由GDK动态注入到java.lang.Object中的。

l  您可以使用collecteach或者eachWithIndex方法遍历字符串,而且这些方法也属于java.lang.Object的一部分。

l  您可对字符串使用操作符。操作符“+”完成字符串联接;“-”则最多去掉一个右操作数的实例;“*”按照给定的数字复制字符串;next实现字符串最后一个字节自增;previous实现字符串最后一个字节自减。

l  您可对StringsStringBuffersStringBuilders使用下标操作符,也可以在下标操作符中使用range和负索引(即索引可以是负数,计数从右边开始)

你可能感兴趣的:(java,jdk,数据结构,grails,groovy)