5.閉包
閉包在我們groovy
中起著很大比重,如果想要學好groovy
,閉包一定得掌握好,
在我們build.gradle
其實就有很多閉包使用:
如:
android{
sourceSets {
main{
jniLibs.srcDirs = ['libs']
}
}
}
這里面的
android {}
其實就是一個閉包結構,其內部的sourceSets{}
又是閉包中的閉包,可以看到閉包在我們的gradle
中無處不在.
學好閉包真的很關鍵
常用閉包方式:
{'abc'}
{ -> 'abc'}
{ -> "abc"+$it}
{ String name -> 'abc'}
{ name -> "abc${name}"}
{ name,age -> "abc${name}"+age}
5.1:閉包的定義及基本方法
def closer = {1234}
closer()
closer.call()
閉包參數
:帶參數的閉包 使用 -> 如果是一個參數可以直接使用it代替和kotlin中的lambda類型類似
def closerParam = { name,age ->
println "hello groovy:${name}:${age}"
'return hei'
}
def result = closerParam("lily",123)
閉包返回值
:閉包返回值 如果沒有定義return則直接返回最后一句話的返回值
println result //打印結果:return hei
5.2:閉包使用詳解
- 5.2.1:與
基本類型
結合使用:
//upto:實現階乘
int x= fab_upTo(5)
println(x)
int fab_upTo(int number){
int result = 1
1.upto(number,{result*=it})
return result
}
//downto:實現階乘
int x1= fab_downTo(5)
println(x1)
int fab_downTo(int number){
int result = 1
number.downto(1){result*=it}
return result
}
//times:實現累加
int x2 = cal(101)
println(x2)
int cal(int number){
def result = 0;
number.times {
result+=it
}
return result
}
- 5.2.2:與
String
結合使用
String str = "the 2 and 3 is 5"
//each:遍歷查找,返回值是str自己
println str.each {temp ->
print temp.multiply(2)
}
//find查找一個符合條件的
println str.find {
it.isNumber()
}
//findAll查找所有符合條件的,返回的是一個集合
println str.findAll {
it.isNumber()
}
//any表示查找只要存在一個符合的就是true
println str.any { s ->
s.isNumber()
}
//every表示全部元素都要符合的就是true
println str.every {
it.isNumber()
}
//將所有字符進行轉化后,放到一個List中返回
def list = str.collect {
it.toUpperCase()
}
println(list)
-
5.2.3:與
數據結構
結合使用:這部分操作和與String結合使用類似,不再講解
-
5.2.4:與
文件
結合使用這部分在講解到文件操作的時候,再進行具體講解
5.3:閉包進階詳解
- 5.3.1:閉包關鍵變量:
this,owner,delegate
情況1
:一般情況:
def scriptCloser = {
println "scriptCloser:this:${this}"
println "scriptCloser:owner:${owner}"
println "scriptCloser:delegate:${delegate}"
}
調用:scriptCloser()
結果:
scriptCloser:this:variable.Closer@58a63629
scriptCloser:owner:variable.Closer@58a63629
scriptCloser:delegate:variable.Closer@58a63629
可以看到一般情況下:三種都是相等的:都代表當前閉包對象
情況2
:我們來看下面的情況:閉包中有閉包
def nestClosure = {
def innerClosure = {
println "innerClosure:this:"+this.getClass()
println "innerClosure:owner:${owner.getClass()}"
println "innerClosure:delegate:${delegate.getClass()}"
}
innerClosure()
}
nestClosure()
結果:
innerClosure:this:class variable.Closer
innerClosure:owner:class variable.Closer$_run_closure10
innerClosure:delegate:class variable.Closer$_run_closure10
看到在閉包中調用閉包:
this還是執行外部的Closer對象,而
owner
和delegate
變為了Closer
的內部閉包對象
情況3
:最后來看一種情況:使用delegate委托
class Student{
def name
def pretty = {println "my name is ${name}"}
void showName(){
pretty.call()
}
}
class Teacher{
def name
}
Student stu1 = new Student(name: 'yuhb')
Teacher tea1 = new Teacher(name: 'lily')
//改變委托delegate
stu1.pretty.delegate = tea1
stu1.showName()
//設置委托策略
stu1.pretty.resolveStrategy = Closure.DELEGATE_FIRST
stu1.showName()
結果:
my name is yuhb
my name is lily
通過上面三種情況:
總結出:
this
:指向最外部的Closer對象owner
:執行當前閉包的Closer對象,特指當前,所以對閉包中的閉包,指向內部的閉包delegate
:這個是閉包的代理對象,如果有單獨配置這個delegate,且設置了委托策略 =DELEGATE_FIRST
, 則閉包中的所有內部屬性都會優先使用delegate中的對象
下面我們就來講解閉包的委托策略
- 5.3.2:閉包
委托策略
閉包中給我提供了以下策略:
//優先使用ower中的屬性
public static final int OWNER_FIRST = 0;
//優先使用delegate中的屬性
public static final int DELEGATE_FIRST = 1;
//只是有owner中的屬性
public static final int OWNER_ONLY = 2;
//只是有delegate中的屬性
public static final int DELEGATE_ONLY = 3;
//使用this中的屬性
public static final int TO_SELF = 4;
通過5.3.1中的例子,我們也可以看出Groovy默認使用的是OWNER_FIRST的委托策略
6.文件
groovy文件操作完全兼容java的文件操作,但groovy集成了自己的高階使用方式
- 讀文件:
withReader
def file = new File('../../hello_groovy.iml')
def buf1 = file.withReader {reader ->
char[] buf = new char[100]
reader.read(buf)
buf
}
println buf1
- 寫文件:
withWriter
//寫文件:withWriter:實現文件拷貝操作
def result = copy('../../hello_groovy1.iml','../../hello_groovy.iml')
println result
def copy(String desFilePath,String srcFilePath){
try {
File desFile = new File(desFilePath)
if(!desFile.exists()){
desFile.createNewFile()
}
File srcFile = new File(srcFilePath)
if(!srcFile.exists()){
return false
}else{
srcFile.withReader {reader ->
def lines = reader.readLines()
desFile.withWriter {writer ->
lines.each {line ->
writer.write(line+'\\r\\n')
}
}
return true
}
}
}catch(Exception e){
return false
}
}
- 讀對象:
withObjectInputStream readObject
Groovy不僅可以寫文件,還可以寫入和讀取對象操作
//讀對象
def ob1 = readObject('../../person.bin')
println ob1
def readObject(String srcFilePath){
try {
File desFile = new File(srcFilePath)
if(!desFile.exists()){
return false
}
desFile.withObjectInputStream {
def person = it.readObject()
println person.name
}
return true
}catch(Exception e){
return false
}
}
- 寫對象:
withObjectOutputStream writeObject
//寫對象:
Person person = new Person(name: 'uihb',age: 32)
saveObject(person,'../../person.bin')
def saveObject(Object obj,String desFilePath){
try {
File desFile = new File(desFilePath)
if(!desFile.exists()){
desFile.createNewFile()
}
if(obj != null){
desFile.withObjectOutputStream {
it.writeObject(obj)
}
}
}catch(Exception e){
return false
}
}
7.Json
- 7.1:Object轉Json字符串轉
//1.Object 轉JSon
def personList = [
new Person(name: 'lily',age: 12),
new Person(name: 'lucy',age: 14),
new Person(name: 'kare',age: 18)
]
def jsonPerson = JsonOutput.toJson(personList)
println JsonOutput.prettyPrint(jsonPerson)
- 7.2:Json字符串轉Object
//2.JSon轉Object
def jsonSlurper = new JsonSlurper()
def obj = jsonSlurper.parseText(jsonPerson)
println(obj[0].name)
從網絡獲取Json數據操作:
這里引入OkHttp
def getNetWork(String url){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.get()
.build();
Call call = client.newCall(request)
call.enqueue(new Callback() {
@Override
void onFailure(Request _request, IOException e) {
}
@Override
void onResponse(Response response) throws IOException {
def res = new String(response.body().bytes())
println res
JsonSlurper jsonSlurper1 = new JsonSlurper()
Version objetres = (Version)jsonSlurper1.parseText(res)
println objetres.ecode
}
})
sleep(10000)
}
class Version{
int ecode
String emsg
CurrentVersion data
}
class CurrentVersion{
String currentVersion
}
-
JAVA
+關注
關注
19文章
2960瀏覽量
104565 -
開發
+關注
關注
0文章
367瀏覽量
40811 -
gradle
+關注
關注
0文章
26瀏覽量
703
發布評論請先 登錄
相關推薦
評論