讀取assets中的文本內(nèi)容
resources.assets.open("test.txt").let {
it.buffered().reader().use { reader ->
Log.e("test", "${reader.readText()}")
}
}
統(tǒng)計(jì)字符出現(xiàn)的次數(shù)("io.reactivex:rxjava:1.2.1")
/**
* filter中過(guò)濾掉空字符
* groupBy 分組
* o.count 進(jìn)行統(tǒng)計(jì),得到的是一個(gè)observable
*/
// Observable.from(txt.toCharArray().asIterable()).filter { !it.isWhitespace() }.groupBy { it }.map(::println)
Observable.from(txt.toCharArray().asIterable()).filter { !it.isWhitespace() }.groupBy { it }.map { o ->
o.count().subscribe {
println("key = ${o.key} , count = $it")
}
}.subscribe()
retrofit發(fā)送get請(qǐng)求
interface GithubService {
@GET("/repos/enbandari/Kotlin-Tutorials/stargazers")
fun getUserInfos(): Call<List<User>>
}
// object單例類
object ServiceManager {
val apiService: GithubService by lazy {
Retrofit.Builder().baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create()).build().create(GithubService::class.java)
}
}
data class User(val login: String, val id: Long, val avatar_url: String)
單例類的5種實(shí)現(xiàn)方式對(duì)比
java
第一種方式
public class LazyNotThreadSafe {
private static LazyNotThreadSafe INSTANCE;
private LazyNotThreadSafe() {
}
public static LazyNotThreadSafe getInstance() {
if (INSTANCE == null) {
INSTANCE = new LazyNotThreadSafe();
}
return INSTANCE;
}
}
第二種方式
public class LazyThreadSafeDoubleCheck {
private static LazyThreadSafeDoubleCheck INSTANCE;
private LazyThreadSafeDoubleCheck() {
}
public static LazyThreadSafeDoubleCheck getInstance() {
if (INSTANCE == null) {
synchronized (LazyThreadSafeDoubleCheck.class) {
if (INSTANCE == null) {
//初始化時(shí)分為實(shí)例化和賦值兩步, 盡管我們把這一步寫成下面的語(yǔ)句,
// 但Java虛擬機(jī)并不保證其他線程『眼中』這兩步的順序究竟是怎么樣的
INSTANCE = new LazyThreadSafeDoubleCheck();
}
}
}
return INSTANCE;
}
}
第三種方式
public class LazyThreadSafeStaticInnerClass {
private static class Holder {
private static LazyThreadSafeStaticInnerClass INSTANCE = new LazyThreadSafeStaticInnerClass();
}
private LazyThreadSafeStaticInnerClass() {
}
public static LazyThreadSafeStaticInnerClass getInstance() {
return Holder.INSTANCE;
}
}
第四種方式
public class LazyThreadSafeSynchronized {
private static LazyThreadSafeSynchronized INSTANCE;
private LazyThreadSafeSynchronized() {
}
public static synchronized LazyThreadSafeSynchronized getInstance() {
if (INSTANCE == null) {
INSTANCE = new LazyThreadSafeSynchronized();
}
return INSTANCE;
}
}
第五種方式
public class PlainOldSingleton {
private static PlainOldSingleton INSTANCE = new PlainOldSingleton();
private PlainOldSingleton() {
}
public static PlainOldSingleton getInstance() {
return INSTANCE;
}
}
kotlin
第一種方式
class LazyNotThreadSafe private constructor(){
companion object {
val instance by lazy {
LazyNotThreadSafe()
}
// 下面是另一種等價(jià)的寫法, 獲取單例使用 get 方法
private var instance2: LazyNotThreadSafe? = null
fun get(): LazyNotThreadSafe {
if (instance2 == null)
instance2 = LazyNotThreadSafe()
return instance2!!
}
}
}
第二種方式
class LazyThreadSafeDoubleCheck private constructor() {
companion object {
val instance by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
LazyThreadSafeDoubleCheck()
}
private @Volatile
var instance2: LazyThreadSafeDoubleCheck? = null
fun get(): LazyThreadSafeDoubleCheck {
if (instance2 == null) {
synchronized(this) {
if (instance2 == null) {
instance2 = LazyThreadSafeDoubleCheck()
}
}
}
return instance2!!
}
}
}
第三種方式
class LazyThreadSafeStaticInnerClass private constructor() {
companion object {
fun getInstance() = Holder.instance
}
private object Holder {
val instance= LazyThreadSafeStaticInnerClass()
}
}
第四種方式
class LazyThreadSafeSynchronized private constructor() {
companion object {
private var instance: LazyThreadSafeSynchronized? = null
@Synchronized
fun get(): LazyThreadSafeSynchronized {
if (instance == null)
instance = LazyThreadSafeSynchronized()
return instance!!
}
}
}
第五種方式
/**
* 定義的類本身就是單例類
*/
object PlainOldSingleton
動(dòng)態(tài)代理之解決reified不足的問(wèn)題
{
"code": 0,
"message": "ok",
"content": {
"id": 1,
"name": "Unknown",
"songs": [
{
"id": 0,
"name": "Rada"
},
{
"id": 1,
"name": "Olympic Dream"
},
{
"id": 2,
"name": "The Escapist"
}
]
}
}
Gson的擴(kuò)展方法
// 通常情況下使用inline+reified解決泛型不被擦
inline fun <reified T : Any> Gson.fromJson(json: String): T {
return fromJson(json, T::class.java)
}
通過(guò)動(dòng)態(tài)代理獲取到Singer類型
interface Api {
fun getSingerFromJson(json: String): BaseResult<Singer>
}
object ApiFactory {
val api: Api by lazy {
Proxy.newProxyInstance(
ApiFactory.javaClass.classLoader,
arrayOf(Api::class.java)
) { proxy, method, args ->
// 獲取方法的返回值類型
val responseType = method.genericReturnType
val adapter = Gson().getAdapter(TypeToken.get(responseType))
adapter.fromJson(args[0].toString())
} as Api
}
}
代碼示例:
val text = File("result_singer.json").readText()
val result: BaseResult<Singer> = gson.fromJson(text)
BaseResult(code=0, message=ok, content={id=1.0, name=Unknown, songs=[{id=0.0, name=Rada}, {id=1.0, name=Olympic Dream}, {id=2.0, name=The Escapist}]})
代碼示例
val result2: BaseResult<Singer> = ApiFactory.api.getSingerFromJson(text)
println(result2)
BaseResult(code=0, message=ok, content=Singer(id=1, name=Unknown, songs=[Song(id=0, name=Rada), Song(id=1, name=Olympic Dream), Song(id=2, name=The Escapist)]))
使用高階函數(shù)替換java中的回調(diào)接口
java代碼
public class TaskExecutor {
private OnCompletionListener onCompletionListener;
public interface OnCompletionListener {
void onDone(long time);
}
public void setListener(OnCompletionListener listener) {
this.onCompletionListener = listener;
}
public void execute() {
Executors.newSingleThreadExecutor().execute(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("time num " + i);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (onCompletionListener != null) {
onCompletionListener.onDone(new Date().getTime());
}
});
}
}
調(diào)用
val taskExecutor = TaskExecutor()
taskExecutor.setListener {
object : TaskExecutor.OnCompletionListener {
override fun onDone(time: Long) {
println("time = $time")
}
}
}
// taskExecutor.execute()
println()
taskExecutor.setListener {
TaskExecutor.OnCompletionListener { time -> println("time = $time") }
}
// taskExecutor.execute()
// println()
kotlin代碼
class KTTaskExecutor {
// 定義lambda表達(dá)式
private var listener: (Long) -> Unit = {}
// 設(shè)置接口
fun setListener(e: (Long) -> Unit) {
this.listener = e
}
fun exec(e: (Long) -> Unit) {
this.listener = e
Executors.newSingleThreadExecutor().execute {
for (i in 1..5) {
println("index at $i")
}
Thread.sleep(500)
e(Date().time) // 調(diào)用函數(shù)并傳入數(shù)據(jù)
}
}
}
未改造前
class Request(val url: String) {
public fun run(callback: Callback) {
async {
val readText = URL(url).readText()
println("${javaClass.simpleName} , $readText")
uiThread {
println("${javaClass.simpleName} , $readText")
callback.done(readText)
}
}
}
public interface Callback {
fun done(data: String)
}
}
改造后
class AdvRequest(val url: String) {
// 匿名接口妒御,需要傳入一個(gè)數(shù)據(jù)
var listener: (String) -> Unit = {}
private set
fun run(e: (String) -> Unit) {
async {
val readText = URL(url).readText()
println("${javaClass.simpleName} , $readText")
uiThread {
println("${javaClass.simpleName} , $readText")
e(readText)
}
}
}
}
調(diào)用
KTTaskExecutor().exec { time ->
println("kttime = $time")
}
btn_exec_net_req.onClick {
rl_loading2.visibility = View.VISIBLE
Request(AppConst.API_REQ_STARTS).run(object : Request.Callback {
override fun done(data: String) {
tv_result.text = data
rl_loading2.visibility = View.GONE
}
})
}
btn_exec_net_req2.onClick {
rl_loading2.visibility = View.VISIBLE
AdvRequest(AppConst.API_REQ_STARTS).run { e ->
tv_result.text = e
rl_loading2.visibility = View.GONE
}
}