Commit 7ab02daa95f3da691b6f0c538f5ab2dd09bab98b

Authored by 韩亚云
2 parents f761e5b0 ee599ef7

Merge branch 'master' of bj.gitlab.cnlive.com:cnlive-team/newModuleStrike

Too many changes to show.

To preserve performance only 17 of 42 files are displayed.

app/strike/build.gradle
@@ -107,7 +107,7 @@ android { @@ -107,7 +107,7 @@ android {
107 zipAlignEnabled true // 是否支持zip 107 zipAlignEnabled true // 是否支持zip
108 // shrinkResources true // 移除无用的resource文件 108 // shrinkResources true // 移除无用的resource文件
109 minifyEnabled false // 是否对代码进行混淆,true表示混淆 109 minifyEnabled false // 是否对代码进行混淆,true表示混淆
110 - debuggable false //是否支持调试 110 + debuggable true //是否支持调试
111 // proguardFiles getDefaultProguardFile('proguard-android.txt'), 111 // proguardFiles getDefaultProguardFile('proguard-android.txt'),
112 // 'proguard-rules.pro' 112 // 'proguard-rules.pro'
113 113
app/strike/src/main/AndroidManifest.xml
1 <?xml version="1.0" encoding="utf-8"?> 1 <?xml version="1.0" encoding="utf-8"?>
2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:tools="http://schemas.android.com/tools"
3 package="com.cnlive.strike"> 4 package="com.cnlive.strike">
4 5
5 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 6 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
6 <uses-permission android:name="android.permission.INTERNET" /> 7 <uses-permission android:name="android.permission.INTERNET" />
7 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 8 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
8 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 9 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
9 -  
10 <application 10 <application
11 android:name=".MyApp" 11 android:name=".MyApp"
12 android:allowBackup="true" 12 android:allowBackup="true"
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 android:roundIcon="@mipmap/ic_launcher_round" 16 android:roundIcon="@mipmap/ic_launcher_round"
17 android:supportsRtl="true" 17 android:supportsRtl="true"
18 android:theme="@style/AppTheme"> 18 android:theme="@style/AppTheme">
  19 +
19 <activity android:name=".demo.activity.DemoActivity" /> 20 <activity android:name=".demo.activity.DemoActivity" />
20 <activity android:name=".MyActivity"></activity> 21 <activity android:name=".MyActivity"></activity>
21 <activity android:name=".imgutil.ImgActivity" /> 22 <activity android:name=".imgutil.ImgActivity" />
app/strike/src/main/java/com/cnlive/strike/MyActivity.java
1 package com.cnlive.strike; 1 package com.cnlive.strike;
2 2
3 3
4 -import android.content.Intent;  
5 import android.text.TextUtils; 4 import android.text.TextUtils;
6 import android.view.View; 5 import android.view.View;
7 6
8 import com.alibaba.android.arouter.facade.annotation.Route; 7 import com.alibaba.android.arouter.facade.annotation.Route;
9 import com.cnlive.core.libs.base.frame.activity.BaseActivity; 8 import com.cnlive.core.libs.base.frame.activity.BaseActivity;
10 -import com.cnlive.core.network.HttpConn;  
11 -import com.cnlive.core.network.NetCallBack;  
12 -import com.cnlive.core.network.model.BaseResult;  
13 -import com.cnlive.libs.wjjpay.model.GroupBalanceInfo;  
14 -import com.cnlive.libs.wjjpay.pay.WjjPay; 9 +import com.cnlive.core.libs.base.util.NetworkUtil;
15 import com.cnlive.moudle.pedometer.commonInfo.CommonInfo; 10 import com.cnlive.moudle.pedometer.commonInfo.CommonInfo;
16 -import com.cnlive.moudle.pedometer.ui.activity.RunLineActivity;  
17 import com.cnlive.strike.databinding.ActivityMyBinding; 11 import com.cnlive.strike.databinding.ActivityMyBinding;
18 import com.cnlive.strike.user.auth.UserService; 12 import com.cnlive.strike.user.auth.UserService;
19 import com.cnlive.strike.xiaojiaspeaker.commonInfo.XiaoJIaCommInfo; 13 import com.cnlive.strike.xiaojiaspeaker.commonInfo.XiaoJIaCommInfo;
20 -import com.cnlive.strike.xiaojiaspeaker.ui.activity.AllDeviceActivity;  
21 -import com.cnlive.strike.xiaojiaspeaker.util.QMUITipDialogUtil;  
22 14
23 @Route(path = "/strick/MyActivity") 15 @Route(path = "/strick/MyActivity")
24 public class MyActivity extends BaseActivity { 16 public class MyActivity extends BaseActivity {
@@ -44,7 +36,10 @@ public class MyActivity extends BaseActivity { @@ -44,7 +36,10 @@ public class MyActivity extends BaseActivity {
44 binding.btnChange.setOnClickListener(new View.OnClickListener() { 36 binding.btnChange.setOnClickListener(new View.OnClickListener() {
45 @Override 37 @Override
46 public void onClick(View v) { 38 public void onClick(View v) {
47 - startActivity(new Intent(MyActivity.this, RunLineActivity.class)); 39 +// Bitmap bitmap=ImageUtils.drawable2Bitmap(getResources().getDrawable(R.mipmap.timg));
  40 + binding.btnChange.setText(NetworkUtil.getNetWorkType(me) + "");
  41 + binding.ivImg.setImageBitmap(screenShot());
  42 +// startActivity(new Intent(MyActivity.this, RunLineActivity.class));
48 43
49 // WjjPay.passwordIsExisting(UserService.getUid(me), new NetCallBack<BaseResult<GroupBalanceInfo>>() { 44 // WjjPay.passwordIsExisting(UserService.getUid(me), new NetCallBack<BaseResult<GroupBalanceInfo>>() {
50 // @Override 45 // @Override
app/strike/src/main/res/layout/activity_my.xml
1 <?xml version="1.0" encoding="utf-8"?> 1 <?xml version="1.0" encoding="utf-8"?>
2 <layout> 2 <layout>
3 3
4 - <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 4 + <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
5 xmlns:app="http://schemas.android.com/apk/res-auto" 5 xmlns:app="http://schemas.android.com/apk/res-auto"
6 xmlns:tools="http://schemas.android.com/tools" 6 xmlns:tools="http://schemas.android.com/tools"
7 android:layout_width="match_parent" 7 android:layout_width="match_parent"
8 android:layout_height="match_parent" 8 android:layout_height="match_parent"
9 tools:context="com.cnlive.strike.MyActivity"> 9 tools:context="com.cnlive.strike.MyActivity">
10 10
11 - <RelativeLayout 11 + <LinearLayout
12 android:id="@+id/fragment_container" 12 android:id="@+id/fragment_container"
13 android:layout_width="match_parent" 13 android:layout_width="match_parent"
14 - android:layout_height="match_parent"> 14 + android:layout_height="match_parent"
  15 + android:orientation="vertical">
15 16
16 <TextView 17 <TextView
17 android:layout_width="wrap_content" 18 android:layout_width="wrap_content"
@@ -23,6 +24,11 @@ @@ -23,6 +24,11 @@
23 android:layout_width="wrap_content" 24 android:layout_width="wrap_content"
24 android:layout_height="wrap_content" 25 android:layout_height="wrap_content"
25 android:text="修改支付密码" /> 26 android:text="修改支付密码" />
26 - </RelativeLayout>  
27 - </RelativeLayout> 27 +
  28 + <ImageView
  29 + android:id="@+id/iv_img"
  30 + android:layout_width="100dp"
  31 + android:layout_height="100dp" />
  32 + </LinearLayout>
  33 + </LinearLayout>
28 </layout> 34 </layout>
29 \ No newline at end of file 35 \ No newline at end of file
build.gradle
@@ -29,22 +29,10 @@ allprojects { @@ -29,22 +29,10 @@ allprojects {
29 } 29 }
30 } 30 }
31 31
32 -////配置全局变量  
33 -//ext {  
34 -// def versionMajor = 1  
35 -// def versionMinor = 5  
36 -// def versionPatch = 6  
37 -// def versionBuild = 0  
38 -// // module依赖库公共版本号  
39 -// versionCode = versionMajor * 1000 + versionMinor * 100 + versionPatch * 10 + versionBuild  
40 -// versionName = "${versionMajor}.${versionMinor}.${versionPatch}.${versionBuild}"  
41 -//  
42 -// compileSdkVersion = 29  
43 -// buildToolsVersion = "29.0.2"  
44 -// minSdkVersion = 19  
45 -// targetSdkVersion = 29  
46 -//}  
47 allprojects { 32 allprojects {
  33 +// configurations.all {
  34 +////// resolutionStrategy.force 'androidx.appcompat:appcompat:1.1.0'
  35 +// }
48 afterEvaluate { 36 afterEvaluate {
49 if (project.parent == null || project.parent == rootProject) return 37 if (project.parent == null || project.parent == rootProject) return
50 38
@@ -69,7 +57,21 @@ allprojects { @@ -69,7 +57,21 @@ allprojects {
69 ] 57 ]
70 } 58 }
71 } 59 }
72 - 60 + //解决引用glide-transformations冲突问题
  61 + packagingOptions {
  62 + exclude "lib/armeabi-v7a/libRSSupport.so"
  63 + exclude "lib/arm64-v8a/librsjni.so"
  64 + exclude "lib/arm64-v8a/libRSSupport.so"
  65 + exclude "lib/x86_64/libRSSupport.so"
  66 + exclude "lib/x86/librsjni.so"
  67 + exclude "lib/x86_64/librsjni.so"
  68 + exclude "lib/armeabi-v7a/librsjni.so"
  69 + exclude "lib/x86/libRSSupport.so"
  70 + exclude "lib/x86_64/librsjni_androidx.so"
  71 + exclude "lib/x86/librsjni_androidx.so"
  72 + exclude "lib/arm64-v8a/librsjni_androidx.so"
  73 + exclude "lib/armeabi-v7a/librsjni_androidx.so"
  74 + }
73 ndk { 75 ndk {
74 abiFilters( 76 abiFilters(
75 "armeabi-v7a" 77 "armeabi-v7a"
cloud/user/src/main/java/com/cnlive/strike/user/auth/UserAccountAuthenticator.java
@@ -8,8 +8,7 @@ import android.accounts.NetworkErrorException; @@ -8,8 +8,7 @@ import android.accounts.NetworkErrorException;
8 import android.content.Context; 8 import android.content.Context;
9 import android.content.Intent; 9 import android.content.Intent;
10 import android.os.Bundle; 10 import android.os.Bundle;
11 -  
12 -import com.cnlive.core.libs.base.util.LogUtil; 11 +import android.util.Log;
13 12
14 13
15 public class UserAccountAuthenticator extends AbstractAccountAuthenticator { 14 public class UserAccountAuthenticator extends AbstractAccountAuthenticator {
@@ -22,7 +21,7 @@ public class UserAccountAuthenticator extends AbstractAccountAuthenticator { @@ -22,7 +21,7 @@ public class UserAccountAuthenticator extends AbstractAccountAuthenticator {
22 } 21 }
23 22
24 public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) { 23 public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) {
25 - LogUtil.d(_tag, accountType + " - " + authTokenType); 24 + Log.d(_tag, accountType + " - " + authTokenType);
26 Bundle ret = new Bundle(); 25 Bundle ret = new Bundle();
27 try { 26 try {
28 Class<?> clazz = Class.forName("com.cnlive.strike.moudle.user.ui.activity.LoginActivity"); 27 Class<?> clazz = Class.forName("com.cnlive.strike.moudle.user.ui.activity.LoginActivity");
@@ -38,42 +37,42 @@ public class UserAccountAuthenticator extends AbstractAccountAuthenticator { @@ -38,42 +37,42 @@ public class UserAccountAuthenticator extends AbstractAccountAuthenticator {
38 37
39 @Override 38 @Override
40 public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) { 39 public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) {
41 - LogUtil.d(_tag, ".confirmCredentials"); 40 + Log.d(_tag, ".confirmCredentials");
42 return null; 41 return null;
43 } 42 }
44 43
45 44
46 @Override 45 @Override
47 public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) { 46 public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
48 - LogUtil.d(_tag, ".editProperties"); 47 + Log.d(_tag, ".editProperties");
49 return null; 48 return null;
50 } 49 }
51 50
52 51
53 @Override 52 @Override
54 public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle loginOptions) throws NetworkErrorException { 53 public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle loginOptions) throws NetworkErrorException {
55 - LogUtil.d(_tag, ".getAuthToken"); 54 + Log.d(_tag, ".getAuthToken");
56 return null; 55 return null;
57 } 56 }
58 57
59 58
60 @Override 59 @Override
61 public String getAuthTokenLabel(String authTokenType) { 60 public String getAuthTokenLabel(String authTokenType) {
62 - LogUtil.d(_tag, ".getAuthTokenLabel"); 61 + Log.d(_tag, ".getAuthTokenLabel");
63 return null; 62 return null;
64 } 63 }
65 64
66 65
67 @Override 66 @Override
68 public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException { 67 public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException {
69 - LogUtil.d(_tag, ".hasFeatures"); 68 + Log.d(_tag, ".hasFeatures");
70 return null; 69 return null;
71 } 70 }
72 71
73 72
74 @Override 73 @Override
75 public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle loginOptions) { 74 public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle loginOptions) {
76 - LogUtil.d(_tag, ".updateCredentials"); 75 + Log.d(_tag, ".updateCredentials");
77 return null; 76 return null;
78 } 77 }
79 78
cloud/user/src/main/java/com/cnlive/strike/user/frame/presenter/QuickLoginPresenter.java
@@ -9,7 +9,7 @@ import com.cnlive.core.libs.base.frame.presenter.BasePresenter; @@ -9,7 +9,7 @@ import com.cnlive.core.libs.base.frame.presenter.BasePresenter;
9 import com.cnlive.core.network.model.BaseResult; 9 import com.cnlive.core.network.model.BaseResult;
10 import com.cnlive.core.network.HttpConn; 10 import com.cnlive.core.network.HttpConn;
11 import com.cnlive.core.network.NetCallBack; 11 import com.cnlive.core.network.NetCallBack;
12 -import com.cnlive.core.libs.base.util.TimerUtil; 12 +import com.cnlive.core.libs.base.util.TimerWaitUtil;
13 import com.cnlive.strike.user.R; 13 import com.cnlive.strike.user.R;
14 import com.cnlive.strike.user.UserUtilAction; 14 import com.cnlive.strike.user.UserUtilAction;
15 import com.cnlive.strike.user.auth.UserService; 15 import com.cnlive.strike.user.auth.UserService;
@@ -34,7 +34,7 @@ import io.reactivex.disposables.Disposable; @@ -34,7 +34,7 @@ import io.reactivex.disposables.Disposable;
34 */ 34 */
35 35
36 public class QuickLoginPresenter extends BasePresenter<QuickLoginView> { 36 public class QuickLoginPresenter extends BasePresenter<QuickLoginView> {
37 - private TimerUtil timerUtil; //计时工具类 37 + private TimerWaitUtil timerUtil; //计时工具类
38 38
39 private Disposable event; 39 private Disposable event;
40 private Disposable sendMsgBefQuickLogin; 40 private Disposable sendMsgBefQuickLogin;
@@ -69,11 +69,11 @@ public class QuickLoginPresenter extends BasePresenter&lt;QuickLoginView&gt; { @@ -69,11 +69,11 @@ public class QuickLoginPresenter extends BasePresenter&lt;QuickLoginView&gt; {
69 private void startTimer() { 69 private void startTimer() {
70 if (timerUtil != null) timerUtil.cancel(); 70 if (timerUtil != null) timerUtil.cancel();
71 71
72 - timerUtil = new TimerUtil(); 72 + timerUtil = new TimerWaitUtil();
73 timerUtil.setTotalTime(60_000);//设置毫秒数 73 timerUtil.setTotalTime(60_000);//设置毫秒数
74 timerUtil.setIntervalTime(500);//设置间隔数 74 timerUtil.setIntervalTime(500);//设置间隔数
75 timerUtil.start(); 75 timerUtil.start();
76 - timerUtil.setTimerLiener(new TimerUtil.TimeListener() { 76 + timerUtil.setTimerLiener(new TimerWaitUtil.TimeListener() {
77 @Override 77 @Override
78 public void onFinish() { 78 public void onFinish() {
79 ifViewAttached(view -> view.onTimerFinish()); 79 ifViewAttached(view -> view.onTimerFinish());
cloud/user/src/main/java/com/cnlive/strike/user/ui/activity/FirstLoginActivity.java
1 package com.cnlive.strike.user.ui.activity; 1 package com.cnlive.strike.user.ui.activity;
2 2
3 -import android.content.Intent;  
4 import android.os.Bundle; 3 import android.os.Bundle;
5 import android.text.TextUtils; 4 import android.text.TextUtils;
6 5
7 -import androidx.annotation.NonNull;  
8 -import androidx.fragment.app.FragmentManager;  
9 -  
10 import com.cnlive.core.libs.base.frame.activity.BaseActivity; 6 import com.cnlive.core.libs.base.frame.activity.BaseActivity;
11 import com.cnlive.core.libs.base.util.AlertUtil; 7 import com.cnlive.core.libs.base.util.AlertUtil;
12 import com.cnlive.core.libs.base.util.DoublePressed; 8 import com.cnlive.core.libs.base.util.DoublePressed;
13 -import com.cnlive.core.libs.base.util.FragmentUtil;  
14 import com.cnlive.strike.user.R; 9 import com.cnlive.strike.user.R;
15 import com.cnlive.strike.user.ui.fragment.FirstLoginFragment; 10 import com.cnlive.strike.user.ui.fragment.FirstLoginFragment;
16 11
cloud/user/src/main/java/com/cnlive/strike/user/ui/activity/LoginActivity.java
@@ -6,17 +6,11 @@ import android.content.Intent; @@ -6,17 +6,11 @@ import android.content.Intent;
6 import android.net.Uri; 6 import android.net.Uri;
7 7
8 import androidx.annotation.NonNull; 8 import androidx.annotation.NonNull;
9 -import androidx.fragment.app.Fragment;  
10 -import androidx.fragment.app.FragmentManager;  
11 9
12 import com.alibaba.android.arouter.facade.annotation.Route; 10 import com.alibaba.android.arouter.facade.annotation.Route;
13 import com.cnlive.core.libs.base.frame.activity.BaseActivity; 11 import com.cnlive.core.libs.base.frame.activity.BaseActivity;
14 import com.cnlive.core.libs.base.frame.fragment.BaseFragment; 12 import com.cnlive.core.libs.base.frame.fragment.BaseFragment;
15 -import com.cnlive.core.libs.base.util.FragmentUtil;  
16 -import com.cnlive.strike.user.R;  
17 import com.cnlive.strike.user.ui.fragment.QuickLoginFragment; 13 import com.cnlive.strike.user.ui.fragment.QuickLoginFragment;
18 -import com.me.yokeyword.fragmentation.anim.DefaultHorizontalAnimator;  
19 -import com.me.yokeyword.fragmentation.anim.FragmentAnimator;  
20 14
21 /** 15 /**
22 * @author Lynn 16 * @author Lynn
config.gradle
@@ -20,7 +20,7 @@ ext { @@ -20,7 +20,7 @@ ext {
20 //用户 20 //用户
21 core_network: project(':core:network'), 21 core_network: project(':core:network'),
22 //基础库 22 //基础库
23 - core_base: project(':core:base') 23 + core_base : project(':core:base')
24 24
25 ] 25 ]
26 26
@@ -34,11 +34,15 @@ ext { @@ -34,11 +34,15 @@ ext {
34 api : 'com.alibaba:arouter-api:1.5.0', 34 api : 'com.alibaba:arouter-api:1.5.0',
35 compiler: 'com.alibaba:arouter-compiler:1.2.2' 35 compiler: 'com.alibaba:arouter-compiler:1.2.2'
36 ] 36 ]
  37 +
37 //图片加载库Glide 38 //图片加载库Glide
38 glide = [ 39 glide = [
39 - api : 'com.github.bumptech.glide:glide:4.10.0',  
40 - transformations: 'jp.wasabeef:glide-transformations:3.0.1',  
41 - compiler : 'com.github.bumptech.glide:compiler:4.10.0' 40 + api : 'com.github.bumptech.glide:glide:4.10.0',
  41 + compiler : 'com.github.bumptech.glide:compiler:4.10.0',
  42 + //图片加载特效
  43 + transformations : 'jp.wasabeef:glide-transformations:4.1.0',
  44 + //图片滤镜
  45 + transformations_gpuimage: 'jp.co.cyberagent.android:gpuimage:2.0.4'
42 ] 46 ]
43 test = [ 47 test = [
44 junit : 'junit:junit:4.12', 48 junit : 'junit:junit:4.12',
@@ -46,7 +50,7 @@ ext { @@ -46,7 +50,7 @@ ext {
46 espresso: 'androidx.test.espresso:espresso-core:3.2.0' 50 espresso: 'androidx.test.espresso:espresso-core:3.2.0'
47 ] 51 ]
48 52
49 - //Maven Base库配置 53 +//Maven Base库配置
50 moudle_cnlive_base = [ 54 moudle_cnlive_base = [
51 //编译方式 55 //编译方式
52 debug : false, 56 debug : false,
@@ -113,7 +117,9 @@ ext { @@ -113,7 +117,9 @@ ext {
113 cardviewV7 : 'com.android.support:cardview-v7:28.0.0', 117 cardviewV7 : 'com.android.support:cardview-v7:28.0.0',
114 dataBinding : 'com.android.databinding.library:3.5.1' 118 dataBinding : 'com.android.databinding.library:3.5.1'
115 ] 119 ]
116 - //基础三方库 120 +
  121 +
  122 +//基础三方库
117 base_librarys = [ 123 base_librarys = [
118 library.logger, 124 library.logger,
119 //视讯云加密库 125 //视讯云加密库
@@ -137,6 +143,7 @@ ext { @@ -137,6 +143,7 @@ ext {
137 //图片加载Glide 143 //图片加载Glide
138 glide.api, 144 glide.api,
139 glide.transformations, 145 glide.transformations,
  146 + glide.transformations_gpuimage,
140 //使用androidx 147 //使用androidx
141 androidx.appcompat, 148 androidx.appcompat,
142 androidx.constraintlayout, 149 androidx.constraintlayout,
@@ -164,7 +171,8 @@ ext { @@ -164,7 +171,8 @@ ext {
164 router.compiler 171 router.compiler
165 ] 172 ]
166 173
167 - //正式签名配置 174 +
  175 +//正式签名配置
168 Properties properties = new Properties() 176 Properties properties = new Properties()
169 properties.load(project.rootProject.file('local.properties').newDataInputStream()) 177 properties.load(project.rootProject.file('local.properties').newDataInputStream())
170 178
core/base/src/main/java/com/cnlive/core/libs/base/frame/activity/BaseActivity.java
@@ -7,6 +7,9 @@ import android.content.DialogInterface; @@ -7,6 +7,9 @@ import android.content.DialogInterface;
7 import android.content.Intent; 7 import android.content.Intent;
8 import android.content.pm.ActivityInfo; 8 import android.content.pm.ActivityInfo;
9 import android.content.pm.PackageManager; 9 import android.content.pm.PackageManager;
  10 +import android.content.res.Configuration;
  11 +import android.content.res.Resources;
  12 +import android.graphics.Bitmap;
10 import android.graphics.Point; 13 import android.graphics.Point;
11 import android.net.Uri; 14 import android.net.Uri;
12 import android.os.Build; 15 import android.os.Build;
@@ -24,6 +27,7 @@ import android.view.inputmethod.InputMethodManager; @@ -24,6 +27,7 @@ import android.view.inputmethod.InputMethodManager;
24 import androidx.annotation.ColorInt; 27 import androidx.annotation.ColorInt;
25 import androidx.annotation.ColorRes; 28 import androidx.annotation.ColorRes;
26 import androidx.annotation.DrawableRes; 29 import androidx.annotation.DrawableRes;
  30 +import androidx.annotation.IntDef;
27 import androidx.annotation.IntRange; 31 import androidx.annotation.IntRange;
28 import androidx.annotation.NonNull; 32 import androidx.annotation.NonNull;
29 import androidx.annotation.Nullable; 33 import androidx.annotation.Nullable;
@@ -59,6 +63,10 @@ import com.me.yokeyword.fragmentation_swipeback.core.ISwipeBackActivity; @@ -59,6 +63,10 @@ import com.me.yokeyword.fragmentation_swipeback.core.ISwipeBackActivity;
59 import com.me.yokeyword.fragmentation_swipeback.core.SwipeBackActivityDelegate; 63 import com.me.yokeyword.fragmentation_swipeback.core.SwipeBackActivityDelegate;
60 import com.orhanobut.logger.Logger; 64 import com.orhanobut.logger.Logger;
61 65
  66 +import java.lang.annotation.ElementType;
  67 +import java.lang.annotation.Retention;
  68 +import java.lang.annotation.RetentionPolicy;
  69 +import java.lang.annotation.Target;
62 import java.lang.reflect.Field; 70 import java.lang.reflect.Field;
63 import java.util.ArrayList; 71 import java.util.ArrayList;
64 import java.util.List; 72 import java.util.List;
@@ -214,6 +222,94 @@ public abstract class BaseActivity&lt;V extends BaseView, P extends BasePresenter&lt;V @@ -214,6 +222,94 @@ public abstract class BaseActivity&lt;V extends BaseView, P extends BasePresenter&lt;V
214 isAllowScreenRoate = allowScreenRoate; 222 isAllowScreenRoate = allowScreenRoate;
215 } 223 }
216 224
  225 +
  226 + /**
  227 + * 设置屏幕为横屏
  228 + * Set the screen to landscape.
  229 + */
  230 + public void setLandscape() {
  231 + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
  232 + }
  233 +
  234 + /**
  235 + * 设置屏幕为竖屏
  236 + * Set the screen to portrait.
  237 + */
  238 + public void setPortrait() {
  239 + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  240 + }
  241 +
  242 +
  243 + /**
  244 + * 是否横屏
  245 + * Return whether screen is landscape.
  246 + *
  247 + * @return {@code true}: yes<br>{@code false}: no
  248 + */
  249 + public boolean isLandscape() {
  250 + return getResources().getConfiguration().orientation
  251 + == Configuration.ORIENTATION_LANDSCAPE;
  252 + }
  253 +
  254 + /**
  255 + * 是否竖屏
  256 + * Return whether screen is portrait.
  257 + *
  258 + * @return {@code true}: yes<br>{@code false}: no
  259 + */
  260 + public boolean isPortrait() {
  261 + return getResources().getConfiguration().orientation
  262 + == Configuration.ORIENTATION_PORTRAIT;
  263 + }
  264 +
  265 + /**
  266 + * 截屏
  267 + * Return the bitmap of screen.
  268 + *
  269 + * @return the bitmap of screen
  270 + */
  271 + public Bitmap screenShot() {
  272 + return screenShot(this, false);
  273 + }
  274 +
  275 + public Bitmap screenShot(boolean isDeleteStatusBar) {
  276 + return screenShot(this, isDeleteStatusBar);
  277 + }
  278 +
  279 + /**
  280 + * Return the bitmap of screen.
  281 + *
  282 + * @param activity The activity.
  283 + * @param isDeleteStatusBar True to delete status bar, false otherwise.
  284 + * @return the bitmap of screen
  285 + */
  286 + private Bitmap screenShot(@NonNull final Activity activity, boolean isDeleteStatusBar) {
  287 + View decorView = activity.getWindow().getDecorView();
  288 + decorView.setDrawingCacheEnabled(true);
  289 + decorView.setWillNotCacheDrawing(false);
  290 + Bitmap bmp = decorView.getDrawingCache();
  291 + if (bmp == null) return null;
  292 + DisplayMetrics dm = new DisplayMetrics();
  293 + activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
  294 + Bitmap ret;
  295 + if (isDeleteStatusBar) {
  296 + Resources resources = activity.getResources();
  297 + int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
  298 + int statusBarHeight = resources.getDimensionPixelSize(resourceId);
  299 + ret = Bitmap.createBitmap(
  300 + bmp,
  301 + 0,
  302 + statusBarHeight,
  303 + dm.widthPixels,
  304 + dm.heightPixels - statusBarHeight
  305 + );
  306 + } else {
  307 + ret = Bitmap.createBitmap(bmp, 0, 0, dm.widthPixels, dm.heightPixels);
  308 + }
  309 + decorView.destroyDrawingCache();
  310 + return ret;
  311 + }
  312 +
217 /** 313 /**
218 * 保证同一按钮在1秒内只会响应一次点击事件 314 * 保证同一按钮在1秒内只会响应一次点击事件
219 */ 315 */
@@ -235,18 +331,6 @@ public abstract class BaseActivity&lt;V extends BaseView, P extends BasePresenter&lt;V @@ -235,18 +331,6 @@ public abstract class BaseActivity&lt;V extends BaseView, P extends BasePresenter&lt;V
235 } 331 }
236 332
237 /** 333 /**
238 - * 同一按钮在短时间内可重复响应点击事件  
239 - */  
240 - public abstract class OnMultiClickListener implements View.OnClickListener {  
241 - public abstract void onMultiClick(View view);  
242 -  
243 - @Override  
244 - public void onClick(View v) {  
245 - onMultiClick(v);  
246 - }  
247 - }  
248 -  
249 - /**  
250 * 隐藏软键盘 334 * 隐藏软键盘
251 */ 335 */
252 public void hideSoftInput() { 336 public void hideSoftInput() {
@@ -270,7 +354,6 @@ public abstract class BaseActivity&lt;V extends BaseView, P extends BasePresenter&lt;V @@ -270,7 +354,6 @@ public abstract class BaseActivity&lt;V extends BaseView, P extends BasePresenter&lt;V
270 * 显示软键盘 354 * 显示软键盘
271 */ 355 */
272 public void showSoftInput(View view) { 356 public void showSoftInput(View view) {
273 - // InputMethodManager.SHOW_FORCED);  
274 InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); 357 InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
275 imm.showSoftInput(view, InputMethodManager.SHOW_FORCED); 358 imm.showSoftInput(view, InputMethodManager.SHOW_FORCED);
276 } 359 }
@@ -339,7 +422,8 @@ public abstract class BaseActivity&lt;V extends BaseView, P extends BasePresenter&lt;V @@ -339,7 +422,8 @@ public abstract class BaseActivity&lt;V extends BaseView, P extends BasePresenter&lt;V
339 /** 422 /**
340 * 设置状态栏字体颜色 423 * 设置状态栏字体颜色
341 */ 424 */
342 - public void setStatusBarTextColor(int type) { 425 + // 定义适用于参数的注解,限定取值范围为{STATUS_OPEN, STATUS_CLOSE}
  426 + public void setStatusBarTextColor(@StatusBarConfig.Unit final int type) {
343 if (type == StatusBarConfig.BLACK) { 427 if (type == StatusBarConfig.BLACK) {
344 StatusBarUtil.setStatusBarWrite(this); 428 StatusBarUtil.setStatusBarWrite(this);
345 } else if (type == StatusBarConfig.WHITE) { 429 } else if (type == StatusBarConfig.WHITE) {
@@ -366,7 +450,6 @@ public abstract class BaseActivity&lt;V extends BaseView, P extends BasePresenter&lt;V @@ -366,7 +450,6 @@ public abstract class BaseActivity&lt;V extends BaseView, P extends BasePresenter&lt;V
366 return view; 450 return view;
367 } 451 }
368 452
369 - // protected abstract int getLayoutId();  
370 protected int getBindLayoutId() { 453 protected int getBindLayoutId() {
371 return 0; 454 return 0;
372 } 455 }
core/base/src/main/java/com/cnlive/core/libs/base/frame/fragment/BaseFragment.java
@@ -2,13 +2,12 @@ package com.cnlive.core.libs.base.frame.fragment; @@ -2,13 +2,12 @@ package com.cnlive.core.libs.base.frame.fragment;
2 2
3 import android.app.Activity; 3 import android.app.Activity;
4 import android.content.Intent; 4 import android.content.Intent;
5 -import android.content.pm.ActivityInfo; 5 +import android.graphics.Bitmap;
6 import android.os.Bundle; 6 import android.os.Bundle;
7 import android.view.LayoutInflater; 7 import android.view.LayoutInflater;
8 import android.view.View; 8 import android.view.View;
9 import android.view.ViewGroup; 9 import android.view.ViewGroup;
10 import android.view.animation.Animation; 10 import android.view.animation.Animation;
11 -import android.view.inputmethod.InputMethodManager;  
12 11
13 import androidx.annotation.ColorInt; 12 import androidx.annotation.ColorInt;
14 import androidx.annotation.ColorRes; 13 import androidx.annotation.ColorRes;
@@ -17,7 +16,6 @@ import androidx.annotation.IntRange; @@ -17,7 +16,6 @@ import androidx.annotation.IntRange;
17 import androidx.annotation.NonNull; 16 import androidx.annotation.NonNull;
18 import androidx.annotation.Nullable; 17 import androidx.annotation.Nullable;
19 import androidx.annotation.StringRes; 18 import androidx.annotation.StringRes;
20 -import androidx.core.content.ContextCompat;  
21 import androidx.databinding.DataBindingUtil; 19 import androidx.databinding.DataBindingUtil;
22 import androidx.databinding.ViewDataBinding; 20 import androidx.databinding.ViewDataBinding;
23 21
@@ -26,11 +24,9 @@ import com.cnlive.core.libs.base.frame.activity.BaseActivity; @@ -26,11 +24,9 @@ import com.cnlive.core.libs.base.frame.activity.BaseActivity;
26 import com.cnlive.core.libs.base.frame.presenter.BasePresenter; 24 import com.cnlive.core.libs.base.frame.presenter.BasePresenter;
27 import com.cnlive.core.libs.base.interfaces.OnPermissionResponseListener; 25 import com.cnlive.core.libs.base.interfaces.OnPermissionResponseListener;
28 import com.cnlive.core.libs.base.network.manager.SubscriptionManager; 26 import com.cnlive.core.libs.base.network.manager.SubscriptionManager;
29 -import com.cnlive.core.libs.base.util.ParameterCache;  
30 import com.cnlive.core.libs.base.util.ReflectUtil; 27 import com.cnlive.core.libs.base.util.ReflectUtil;
31 import com.cnlive.core.libs.base.frame.view.BaseView; 28 import com.cnlive.core.libs.base.frame.view.BaseView;
32 import com.cnlive.core.libs.base.util.StatusBarConfig; 29 import com.cnlive.core.libs.base.util.StatusBarConfig;
33 -import com.cnlive.core.libs.base.util.StatusBarUtil;  
34 import com.me.yokeyword.fragmentation.ExtraTransaction; 30 import com.me.yokeyword.fragmentation.ExtraTransaction;
35 import com.me.yokeyword.fragmentation.ISupportFragment; 31 import com.me.yokeyword.fragmentation.ISupportFragment;
36 import com.me.yokeyword.fragmentation.SupportFragmentDelegate; 32 import com.me.yokeyword.fragmentation.SupportFragmentDelegate;
@@ -41,9 +37,6 @@ import com.me.yokeyword.fragmentation_swipeback.core.ISwipeBackFragment; @@ -41,9 +37,6 @@ import com.me.yokeyword.fragmentation_swipeback.core.ISwipeBackFragment;
41 import com.me.yokeyword.fragmentation_swipeback.core.SwipeBackFragmentDelegate; 37 import com.me.yokeyword.fragmentation_swipeback.core.SwipeBackFragmentDelegate;
42 import com.orhanobut.logger.Logger; 38 import com.orhanobut.logger.Logger;
43 39
44 -  
45 -import static android.content.Context.INPUT_METHOD_SERVICE;  
46 -  
47 /** 40 /**
48 * 基类fragment 41 * 基类fragment
49 * 42 *
@@ -232,7 +225,7 @@ public abstract class BaseFragment&lt;V extends BaseView, P extends BasePresenter&lt;V @@ -232,7 +225,7 @@ public abstract class BaseFragment&lt;V extends BaseView, P extends BasePresenter&lt;V
232 /** 225 /**
233 * 设置状态栏字体颜色 226 * 设置状态栏字体颜色
234 */ 227 */
235 - public void setStatusBarTextColor(int type) { 228 + public void setStatusBarTextColor(@StatusBarConfig.Unit int type) {
236 me.setStatusBarTextColor(type); 229 me.setStatusBarTextColor(type);
237 } 230 }
238 231
@@ -244,13 +237,56 @@ public abstract class BaseFragment&lt;V extends BaseView, P extends BasePresenter&lt;V @@ -244,13 +237,56 @@ public abstract class BaseFragment&lt;V extends BaseView, P extends BasePresenter&lt;V
244 me.showSoftInput(); 237 me.showSoftInput();
245 } 238 }
246 239
247 -// /**  
248 -// * 显示软键盘  
249 -// */  
250 -// public void showSoftInput(View view) {  
251 -// me.showSoftInput(view);  
252 -// } 240 + /**
  241 + * 设置屏幕为横屏
  242 + * Set the screen to landscape.
  243 + */
  244 + public void setLandscape() {
  245 + me.setLandscape();
  246 + }
  247 +
  248 + /**
  249 + * 设置屏幕为竖屏
  250 + * Set the screen to portrait.
  251 + */
  252 + public void setPortrait() {
  253 + me.setPortrait();
  254 + }
  255 +
  256 +
  257 + /**
  258 + * 是否横屏
  259 + * Return whether screen is landscape.
  260 + *
  261 + * @return {@code true}: yes<br>{@code false}: no
  262 + */
  263 + public boolean isLandscape() {
  264 + return me.isLandscape();
  265 + }
  266 +
  267 + /**
  268 + * 是否竖屏
  269 + * Return whether screen is portrait.
  270 + *
  271 + * @return {@code true}: yes<br>{@code false}: no
  272 + */
  273 + public boolean isPortrait() {
  274 + return me.isPortrait();
  275 + }
253 276
  277 + /**
  278 + * 截屏
  279 + * Return the bitmap of screen.
  280 + *
  281 + * @return the bitmap of screen
  282 + */
  283 + public Bitmap screenShot() {
  284 + return me.screenShot();
  285 + }
  286 +
  287 + public Bitmap screenShot(boolean isDeleteStatusBar) {
  288 + return me.screenShot(isDeleteStatusBar);
  289 + }
254 290
255 /*********************************************************/ 291 /*********************************************************/
256 //用于进行dip和px转换 292 //用于进行dip和px转换
core/base/src/main/java/com/cnlive/core/libs/base/network/manager/SubscriptionManager.java
@@ -15,16 +15,16 @@ import io.reactivex.disposables.Disposable; @@ -15,16 +15,16 @@ import io.reactivex.disposables.Disposable;
15 * @author ys 15 * @author ys
16 */ 16 */
17 public class SubscriptionManager { 17 public class SubscriptionManager {
18 - public static SubscriptionManager instance;  
19 - public HashMap<String, CompositeDisposable> hashDisposable;//所有订阅关系  
20 - public HashMap<Integer, String> hashTag;//当前activity  
21 - public HashMap<String, Integer> hashTagIndex;//当前activity 18 + private static SubscriptionManager instance;
  19 + private HashMap<String, CompositeDisposable> hashDisposable;//所有订阅关系
  20 + private HashMap<Integer, String> hashTag;//当前activity
  21 + private HashMap<String, Integer> hashTagIndex;//当前activity
22 private String currentClassName; 22 private String currentClassName;
23 23
24 /** 24 /**
25 * 构造函数 new CompositeDisposable对象 25 * 构造函数 new CompositeDisposable对象
26 */ 26 */
27 - public SubscriptionManager() { 27 + public SubscriptionManager() {
28 if (null == hashDisposable) { 28 if (null == hashDisposable) {
29 hashDisposable = new HashMap<>(); 29 hashDisposable = new HashMap<>();
30 } 30 }
@@ -59,7 +59,7 @@ public class SubscriptionManager { @@ -59,7 +59,7 @@ public class SubscriptionManager {
59 //存放当前class映射 59 //存放当前class映射
60 hashTag.put(hashDisposable.size() - 1, TAG); 60 hashTag.put(hashDisposable.size() - 1, TAG);
61 hashTagIndex.put(TAG, hashTag.size() - 1); 61 hashTagIndex.put(TAG, hashTag.size() - 1);
62 - Log.e(TAG, "初始化: "); 62 + Log.d(TAG, "初始化: ");
63 } 63 }
64 } 64 }
65 65
@@ -89,7 +89,7 @@ public class SubscriptionManager { @@ -89,7 +89,7 @@ public class SubscriptionManager {
89 hashTagIndex.remove(TAG); 89 hashTagIndex.remove(TAG);
90 } 90 }
91 } catch (Exception e) { 91 } catch (Exception e) {
92 - Log.e(TAG, "cancel: " + e.getMessage()); 92 + Log.d(TAG, "cancel: " + e.getMessage());
93 } 93 }
94 } 94 }
95 95
@@ -99,16 +99,20 @@ public class SubscriptionManager { @@ -99,16 +99,20 @@ public class SubscriptionManager {
99 * @param disposable 订阅事件 99 * @param disposable 订阅事件
100 */ 100 */
101 public synchronized void add(Disposable disposable) { 101 public synchronized void add(Disposable disposable) {
102 - if (disposable == null) return;  
103 - //每次去除最新的activity进行存放  
104 - if (null != hashDisposable && hashDisposable.size() > 0) {  
105 - if (!TextUtils.isEmpty(currentClassName)) {  
106 - if (null != hashDisposable.get(currentClassName)) {  
107 - //存放当前activity对应的订阅  
108 - hashDisposable.get(currentClassName).add(disposable);  
109 - Log.e(currentClassName, "add: 添加订阅关系" + hashDisposable.size()); 102 + try {
  103 + if (disposable == null) return;
  104 + //每次去除最新的activity进行存放
  105 + if (null != hashDisposable && hashDisposable.size() > 0) {
  106 + if (!TextUtils.isEmpty(currentClassName)) {
  107 + if (null != hashDisposable.get(currentClassName)) {
  108 + //存放当前activity对应的订阅
  109 + hashDisposable.get(currentClassName).add(disposable);
  110 + Log.d(currentClassName, "add: 添加订阅关系" + hashDisposable.size());
  111 + }
110 } 112 }
111 } 113 }
  114 + } catch (Exception e) {
  115 + Log.e("SubscriptionManager", "cancel: " + e.getMessage());
112 } 116 }
113 } 117 }
114 118
@@ -127,20 +131,24 @@ public class SubscriptionManager { @@ -127,20 +131,24 @@ public class SubscriptionManager {
127 * 清除容器所有 131 * 清除容器所有
128 */ 132 */
129 public synchronized void cancelAll() { 133 public synchronized void cancelAll() {
130 - //解除所有订阅  
131 - if (null != hashDisposable && hashDisposable.size() > 0) {  
132 - if (null != hashTag && hashTag.size() > 0) {  
133 - for (int i = 0; i < hashTag.size(); i++) {  
134 - if (null != hashTag.get(i)) {  
135 - if (null != hashDisposable.get(hashTag.get(i))) {  
136 - hashDisposable.get(hashTag.get(i)).clear(); 134 + try {
  135 + //解除所有订阅
  136 + if (null != hashDisposable && hashDisposable.size() > 0) {
  137 + if (null != hashTag && hashTag.size() > 0) {
  138 + for (int i = 0; i < hashTag.size(); i++) {
  139 + if (null != hashTag.get(i)) {
  140 + if (null != hashDisposable.get(hashTag.get(i))) {
  141 + hashDisposable.get(hashTag.get(i)).clear();
  142 + }
137 } 143 }
138 } 144 }
139 } 145 }
140 } 146 }
  147 + hashDisposable.clear();
  148 + hashTag.clear();
  149 + hashTagIndex.clear();
  150 + } catch (Exception e) {
  151 + Log.e("SubscriptionManager", "cancelAll: " + e.getMessage());
141 } 152 }
142 - hashDisposable.clear();  
143 - hashTag.clear();  
144 - hashTagIndex.clear();  
145 } 153 }
146 } 154 }
core/base/src/main/java/com/cnlive/core/libs/base/util/ArrayUtils.java 0 → 100644
  1 +package com.cnlive.core.libs.base.util;
  2 +
  3 +import java.lang.reflect.Array;
  4 +import java.util.ArrayList;
  5 +import java.util.Arrays;
  6 +import java.util.Collections;
  7 +import java.util.Comparator;
  8 +import java.util.LinkedList;
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * <pre>
  13 + * author: blankj
  14 + * blog : http://blankj.com
  15 + * time : 2019/08/10
  16 + * desc : utils about array
  17 + * </pre>
  18 + * newArray : 新建数组
  19 + * newLongArray : 新建长整型数组
  20 + * newIntArray : 新建整型数组
  21 + * newShortArray : 新建 short 数组
  22 + * newCharArray : 新建字符数组
  23 + * newByteArray : 新建字节数组
  24 + * newDoubleArray : 新建双精度数组
  25 + * newFloatArray : 新建浮点数数组
  26 + * newBooleanArray : 新建 boolean 数组
  27 + * isEmpty : 判断数组是否为空
  28 + * getLength : 获取数组长度
  29 + * isSameLength : 判断两数组长度是否相等
  30 + * get : 获取数组的索引值
  31 + * set : 设置数组的索引值
  32 + * equals : 判断数组是否相等
  33 + * reverse : 逆序数组
  34 + * copy : 拷贝数组
  35 + * subArray : 截取数组
  36 + * add : 增加数组
  37 + * remove : 移除指定的索引
  38 + * removeElement : 移除指定的元素
  39 + * indexOf : 查找第一个元素的索引
  40 + * lastIndexOf : 查找最后一个元素的索引
  41 + * contains : 判断是否包含该元素
  42 + * toPrimitive : 装箱数组转基本类型数组
  43 + * toObject : 基本类型数组转装箱数组
  44 + * asList : 转为链表
  45 + * asUnmodifiableList: 转为不可变链表
  46 + * asArrayList : 转为数组链表
  47 + * asLinkedList : 转为双向链表
  48 + * sort : 排序
  49 + * forAllDo : 对所有元素做操作
  50 + * toString : 数组转为字符串
  51 + */
  52 +public class ArrayUtils {
  53 +
  54 + public static final int INDEX_NOT_FOUND = -1;
  55 +
  56 + private ArrayUtils() {
  57 + throw new UnsupportedOperationException("u can't instantiate me...");
  58 + }
  59 +
  60 + /**
  61 + * 新建数组
  62 + * Returns a new array only of those given elements.
  63 + *
  64 + * @param array The array.
  65 + * @return a new array only of those given elements.
  66 + */
  67 + @SafeVarargs
  68 + public static <T> T[] newArray(T... array) {
  69 + return array;
  70 + }
  71 +
  72 + /**
  73 + * 新建长整型数组
  74 + *
  75 + * @param array
  76 + * @return
  77 + */
  78 + public static long[] newLongArray(long... array) {
  79 + return array;
  80 + }
  81 +
  82 + /**
  83 + * 新建整型数组
  84 + *
  85 + * @param array
  86 + * @return
  87 + */
  88 + public static int[] newIntArray(int... array) {
  89 + return array;
  90 + }
  91 +
  92 + /**
  93 + * 新建 short 数组
  94 + *
  95 + * @param array
  96 + * @return
  97 + */
  98 + public static short[] newShortArray(short... array) {
  99 + return array;
  100 + }
  101 +
  102 + /**
  103 + * 新建字符数组
  104 + *
  105 + * @param array
  106 + * @return
  107 + */
  108 + public static char[] newCharArray(char... array) {
  109 + return array;
  110 + }
  111 +
  112 + /**
  113 + * 新建字节数组
  114 + *
  115 + * @param array
  116 + * @return
  117 + */
  118 + public static byte[] newByteArray(byte... array) {
  119 + return array;
  120 + }
  121 +
  122 + /**
  123 + * 新建双精度数组
  124 + *
  125 + * @param array
  126 + * @return
  127 + */
  128 + public static double[] newDoubleArray(double... array) {
  129 + return array;
  130 + }
  131 +
  132 + /**
  133 + * 新建浮点数数组
  134 + *
  135 + * @param array
  136 + * @return
  137 + */
  138 + public static float[] newFloatArray(float... array) {
  139 + return array;
  140 + }
  141 +
  142 + /**
  143 + * 新建 boolean 数组
  144 + *
  145 + * @param array
  146 + * @return
  147 + */
  148 + public static boolean[] newBooleanArray(boolean... array) {
  149 + return array;
  150 + }
  151 +
  152 + /**
  153 + * 判断数组是否为空
  154 + * Return the array is empty.
  155 + *
  156 + * @param array The array.
  157 + * @return {@code true}: yes<br>{@code false}: no
  158 + */
  159 + public static boolean isEmpty(Object array) {
  160 + return getLength(array) == 0;
  161 + }
  162 +
  163 + /**
  164 + * 获取数组长度
  165 + * Return the size of array.
  166 + *
  167 + * @param array The array.
  168 + * @return the size of array
  169 + */
  170 + public static int getLength(Object array) {
  171 + if (array == null) return 0;
  172 + return Array.getLength(array);
  173 + }
  174 +
  175 + /**
  176 + * 判断两数组长度是否相等
  177 + *
  178 + * @param array1
  179 + * @param array2
  180 + * @return
  181 + */
  182 + public static boolean isSameLength(Object array1, Object array2) {
  183 + return getLength(array1) == getLength(array2);
  184 + }
  185 +
  186 + /**
  187 + * 获取数组的索引值
  188 + * Get the value of the specified index of the array.
  189 + *
  190 + * @param array The array.
  191 + * @param index The index into the array.
  192 + * @return the value of the specified index of the array
  193 + */
  194 + public static Object get(Object array, int index) {
  195 + return get(array, index, null);
  196 + }
  197 +
  198 + /**
  199 + * 取数组的索引值,带有默认值
  200 + * Get the value of the specified index of the array.
  201 + *
  202 + * @param array The array.
  203 + * @param index The index into the array.
  204 + * @param defaultValue The default value.
  205 + * @return the value of the specified index of the array
  206 + */
  207 + public static Object get(Object array, int index, Object defaultValue) {
  208 + if (array == null) return defaultValue;
  209 + try {
  210 + return Array.get(array, index);
  211 + } catch (Exception ignore) {
  212 + return defaultValue;
  213 + }
  214 + }
  215 +
  216 + /**
  217 + * 设置数组的索引值
  218 + * Set the value of the specified index of the array.
  219 + *
  220 + * @param array The array.
  221 + * @param index The index into the array.
  222 + * @param value The new value of the indexed component.
  223 + */
  224 + public static void set(Object array, int index, Object value) {
  225 + if (array == null) return;
  226 + Array.set(array, index, value);
  227 + }
  228 +
  229 + /**
  230 + * 判断数组是否相等
  231 + * Return whether the two arrays are equals.
  232 + *
  233 + * @param a One array.
  234 + * @param a2 The other array.
  235 + * @return {@code true}: yes<br>{@code false}: no
  236 + */
  237 + public static boolean equals(Object[] a, Object[] a2) {
  238 + return Arrays.deepEquals(a, a2);
  239 + }
  240 +
  241 + public static boolean equals(boolean[] a, boolean[] a2) {
  242 + return Arrays.equals(a, a2);
  243 + }
  244 +
  245 + public static boolean equals(byte[] a, byte[] a2) {
  246 + return Arrays.equals(a, a2);
  247 + }
  248 +
  249 + public static boolean equals(char[] a, char[] a2) {
  250 + return Arrays.equals(a, a2);
  251 + }
  252 +
  253 + public static boolean equals(double[] a, double[] a2) {
  254 + return Arrays.equals(a, a2);
  255 + }
  256 +
  257 + public static boolean equals(float[] a, float[] a2) {
  258 + return Arrays.equals(a, a2);
  259 + }
  260 +
  261 + public static boolean equals(int[] a, int[] a2) {
  262 + return Arrays.equals(a, a2);
  263 + }
  264 +
  265 + public static boolean equals(short[] a, short[] a2) {
  266 + return Arrays.equals(a, a2);
  267 + }
  268 +
  269 + ///////////////////////////////////////////////////////////////////////////
  270 + // reverse
  271 + ///////////////////////////////////////////////////////////////////////////
  272 +
  273 + /**
  274 + * 逆序数组
  275 + * <p>Reverses the order of the given array.</p>
  276 + *
  277 + * <p>There is no special handling for multi-dimensional arrays.</p>
  278 + *
  279 + * <p>This method does nothing for a <code>null</code> input array.</p>
  280 + *
  281 + * @param array the array to reverse, may be <code>null</code>
  282 + */
  283 + public static <T> void reverse(T[] array) {
  284 + if (array == null) {
  285 + return;
  286 + }
  287 + int i = 0;
  288 + int j = array.length - 1;
  289 + T tmp;
  290 + while (j > i) {
  291 + tmp = array[j];
  292 + array[j] = array[i];
  293 + array[i] = tmp;
  294 + j--;
  295 + i++;
  296 + }
  297 + }
  298 +
  299 + public static void reverse(long[] array) {
  300 + if (array == null) {
  301 + return;
  302 + }
  303 + int i = 0;
  304 + int j = array.length - 1;
  305 + long tmp;
  306 + while (j > i) {
  307 + tmp = array[j];
  308 + array[j] = array[i];
  309 + array[i] = tmp;
  310 + j--;
  311 + i++;
  312 + }
  313 + }
  314 +
  315 + public static void reverse(int[] array) {
  316 + if (array == null) {
  317 + return;
  318 + }
  319 + int i = 0;
  320 + int j = array.length - 1;
  321 + int tmp;
  322 + while (j > i) {
  323 + tmp = array[j];
  324 + array[j] = array[i];
  325 + array[i] = tmp;
  326 + j--;
  327 + i++;
  328 + }
  329 + }
  330 +
  331 + public static void reverse(short[] array) {
  332 + if (array == null) {
  333 + return;
  334 + }
  335 + int i = 0;
  336 + int j = array.length - 1;
  337 + short tmp;
  338 + while (j > i) {
  339 + tmp = array[j];
  340 + array[j] = array[i];
  341 + array[i] = tmp;
  342 + j--;
  343 + i++;
  344 + }
  345 + }
  346 +
  347 + public static void reverse(char[] array) {
  348 + if (array == null) {
  349 + return;
  350 + }
  351 + int i = 0;
  352 + int j = array.length - 1;
  353 + char tmp;
  354 + while (j > i) {
  355 + tmp = array[j];
  356 + array[j] = array[i];
  357 + array[i] = tmp;
  358 + j--;
  359 + i++;
  360 + }
  361 + }
  362 +
  363 + public static void reverse(byte[] array) {
  364 + if (array == null) {
  365 + return;
  366 + }
  367 + int i = 0;
  368 + int j = array.length - 1;
  369 + byte tmp;
  370 + while (j > i) {
  371 + tmp = array[j];
  372 + array[j] = array[i];
  373 + array[i] = tmp;
  374 + j--;
  375 + i++;
  376 + }
  377 + }
  378 +
  379 + public static void reverse(double[] array) {
  380 + if (array == null) {
  381 + return;
  382 + }
  383 + int i = 0;
  384 + int j = array.length - 1;
  385 + double tmp;
  386 + while (j > i) {
  387 + tmp = array[j];
  388 + array[j] = array[i];
  389 + array[i] = tmp;
  390 + j--;
  391 + i++;
  392 + }
  393 + }
  394 +
  395 + public static void reverse(float[] array) {
  396 + if (array == null) {
  397 + return;
  398 + }
  399 + int i = 0;
  400 + int j = array.length - 1;
  401 + float tmp;
  402 + while (j > i) {
  403 + tmp = array[j];
  404 + array[j] = array[i];
  405 + array[i] = tmp;
  406 + j--;
  407 + i++;
  408 + }
  409 + }
  410 +
  411 + public static void reverse(boolean[] array) {
  412 + if (array == null) {
  413 + return;
  414 + }
  415 + int i = 0;
  416 + int j = array.length - 1;
  417 + boolean tmp;
  418 + while (j > i) {
  419 + tmp = array[j];
  420 + array[j] = array[i];
  421 + array[i] = tmp;
  422 + j--;
  423 + i++;
  424 + }
  425 + }
  426 +
  427 + ///////////////////////////////////////////////////////////////////////////
  428 + // copy
  429 + ///////////////////////////////////////////////////////////////////////////
  430 +
  431 + /**
  432 + * 拷贝数组
  433 + * <p>Copies the specified array and handling
  434 + * <code>null</code>.</p>
  435 + *
  436 + * <p>The objects in the array are not cloned, thus there is no special
  437 + * handling for multi-dimensional arrays.</p>
  438 + *
  439 + * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
  440 + *
  441 + * @param array the array to shallow clone, may be <code>null</code>
  442 + * @return the cloned array, <code>null</code> if <code>null</code> input
  443 + */
  444 + public static <T> T[] copy(T[] array) {
  445 + if (array == null) return null;
  446 + return subArray(array, 0, array.length);
  447 + }
  448 +
  449 + public static long[] copy(long[] array) {
  450 + if (array == null) return null;
  451 + return subArray(array, 0, array.length);
  452 + }
  453 +
  454 + public static int[] copy(int[] array) {
  455 + if (array == null) return null;
  456 + return subArray(array, 0, array.length);
  457 + }
  458 +
  459 + public static short[] copy(short[] array) {
  460 + if (array == null) return null;
  461 + return subArray(array, 0, array.length);
  462 + }
  463 +
  464 + public static char[] copy(char[] array) {
  465 + if (array == null) return null;
  466 + return subArray(array, 0, array.length);
  467 + }
  468 +
  469 + public static byte[] copy(byte[] array) {
  470 + if (array == null) return null;
  471 + return subArray(array, 0, array.length);
  472 + }
  473 +
  474 + public static double[] copy(double[] array) {
  475 + if (array == null) return null;
  476 + return subArray(array, 0, array.length);
  477 + }
  478 +
  479 + public static float[] copy(float[] array) {
  480 + if (array == null) return null;
  481 + return subArray(array, 0, array.length);
  482 + }
  483 +
  484 + public static boolean[] copy(boolean[] array) {
  485 + if (array == null) return null;
  486 + return subArray(array, 0, array.length);
  487 + }
  488 +
  489 + private static Object realCopy(Object array) {
  490 + if (array == null) return null;
  491 + return realSubArray(array, 0, getLength(array));
  492 + }
  493 +
  494 + ///////////////////////////////////////////////////////////////////////////
  495 + // subArray
  496 + ///////////////////////////////////////////////////////////////////////////
  497 +
  498 + /**
  499 + * 截取数组
  500 + *
  501 + * @param array
  502 + * @param startIndexInclusive
  503 + * @param endIndexExclusive
  504 + * @param <T>
  505 + * @return
  506 + */
  507 + public static <T> T[] subArray(T[] array, int startIndexInclusive, int endIndexExclusive) {
  508 + //noinspection unchecked
  509 + return (T[]) realSubArray(array, startIndexInclusive, endIndexExclusive);
  510 + }
  511 +
  512 + public static long[] subArray(long[] array, int startIndexInclusive, int endIndexExclusive) {
  513 + return (long[]) realSubArray(array, startIndexInclusive, endIndexExclusive);
  514 + }
  515 +
  516 + public static int[] subArray(int[] array, int startIndexInclusive, int endIndexExclusive) {
  517 + return (int[]) realSubArray(array, startIndexInclusive, endIndexExclusive);
  518 + }
  519 +
  520 + public static short[] subArray(short[] array, int startIndexInclusive, int endIndexExclusive) {
  521 + return (short[]) realSubArray(array, startIndexInclusive, endIndexExclusive);
  522 + }
  523 +
  524 + public static char[] subArray(char[] array, int startIndexInclusive, int endIndexExclusive) {
  525 + return (char[]) realSubArray(array, startIndexInclusive, endIndexExclusive);
  526 + }
  527 +
  528 + public static byte[] subArray(byte[] array, int startIndexInclusive, int endIndexExclusive) {
  529 + return (byte[]) realSubArray(array, startIndexInclusive, endIndexExclusive);
  530 + }
  531 +
  532 + public static double[] subArray(double[] array, int startIndexInclusive, int endIndexExclusive) {
  533 + return (double[]) realSubArray(array, startIndexInclusive, endIndexExclusive);
  534 + }
  535 +
  536 + public static float[] subArray(float[] array, int startIndexInclusive, int endIndexExclusive) {
  537 + return (float[]) realSubArray(array, startIndexInclusive, endIndexExclusive);
  538 + }
  539 +
  540 + public static boolean[] subArray(boolean[] array, int startIndexInclusive, int endIndexExclusive) {
  541 + return (boolean[]) realSubArray(array, startIndexInclusive, endIndexExclusive);
  542 + }
  543 +
  544 + private static Object realSubArray(Object array, int startIndexInclusive, int endIndexExclusive) {
  545 + if (array == null) {
  546 + return null;
  547 + }
  548 + if (startIndexInclusive < 0) {
  549 + startIndexInclusive = 0;
  550 + }
  551 + int length = getLength(array);
  552 + if (endIndexExclusive > length) {
  553 + endIndexExclusive = length;
  554 + }
  555 + int newSize = endIndexExclusive - startIndexInclusive;
  556 + Class type = array.getClass().getComponentType();
  557 + if (newSize <= 0) {
  558 + return Array.newInstance(type, 0);
  559 + }
  560 + Object subArray = Array.newInstance(type, newSize);
  561 + System.arraycopy(array, startIndexInclusive, subArray, 0, newSize);
  562 + return subArray;
  563 + }
  564 +
  565 + ///////////////////////////////////////////////////////////////////////////
  566 + // add
  567 + ///////////////////////////////////////////////////////////////////////////
  568 +
  569 + /**
  570 + * 增加数组
  571 + * <p>Copies the given array and adds the given element at the end of the new array.</p>
  572 + *
  573 + * <p>The new array contains the same elements of the input
  574 + * array plus the given element in the last position. The component type of
  575 + * the new array is the same as that of the input array.</p>
  576 + *
  577 + * <p>If the input array is <code>null</code>, a new one element array is returned
  578 + * whose component type is the same as the element.</p>
  579 + *
  580 + * <pre>
  581 + * ArrayUtils.realAdd(null, null) = [null]
  582 + * ArrayUtils.realAdd(null, "a") = ["a"]
  583 + * ArrayUtils.realAdd(["a"], null) = ["a", null]
  584 + * ArrayUtils.realAdd(["a"], "b") = ["a", "b"]
  585 + * ArrayUtils.realAdd(["a", "b"], "c") = ["a", "b", "c"]
  586 + * </pre>
  587 + *
  588 + * @param array the array to "realAdd" the element to, may be <code>null</code>
  589 + * @param element the object to realAdd
  590 + * @return A new array containing the existing elements plus the new element
  591 + */
  592 + public static <T> T[] add(T[] array, T element) {
  593 + Class type = array != null ? array.getClass() : (element != null ? element.getClass() : Object.class);
  594 + return (T[]) realAddOne(array, element, type);
  595 + }
  596 +
  597 + public static boolean[] add(boolean[] array, boolean element) {
  598 + return (boolean[]) realAddOne(array, element, Boolean.TYPE);
  599 + }
  600 +
  601 + public static byte[] add(byte[] array, byte element) {
  602 + return (byte[]) realAddOne(array, element, Byte.TYPE);
  603 + }
  604 +
  605 + public static char[] add(char[] array, char element) {
  606 + return (char[]) realAddOne(array, element, Character.TYPE);
  607 + }
  608 +
  609 + public static double[] add(double[] array, double element) {
  610 + return (double[]) realAddOne(array, element, Double.TYPE);
  611 + }
  612 +
  613 + public static float[] add(float[] array, float element) {
  614 + return (float[]) realAddOne(array, element, Float.TYPE);
  615 + }
  616 +
  617 + public static int[] add(int[] array, int element) {
  618 + return (int[]) realAddOne(array, element, Integer.TYPE);
  619 + }
  620 +
  621 + public static long[] add(long[] array, long element) {
  622 + return (long[]) realAddOne(array, element, Long.TYPE);
  623 + }
  624 +
  625 + public static short[] add(short[] array, short element) {
  626 + return (short[]) realAddOne(array, element, Short.TYPE);
  627 + }
  628 +
  629 + private static Object realAddOne(Object array, Object element, Class newArrayComponentType) {
  630 + Object newArray;
  631 + int arrayLength = 0;
  632 + if (array != null) {
  633 + arrayLength = getLength(array);
  634 + newArray = Array.newInstance(array.getClass().getComponentType(), arrayLength + 1);
  635 + System.arraycopy(array, 0, newArray, 0, arrayLength);
  636 + } else {
  637 + newArray = Array.newInstance(newArrayComponentType, 1);
  638 + }
  639 + Array.set(newArray, arrayLength, element);
  640 + return newArray;
  641 + }
  642 +
  643 + /**
  644 + * <p>Adds all the elements of the given arrays into a new array.</p>
  645 + * <p>The new array contains all of the element of <code>array1</code> followed
  646 + * by all of the elements <code>array2</code>. When an array is returned, it is always
  647 + * a new array.</p>
  648 + *
  649 + * <pre>
  650 + * ArrayUtils.add(null, null) = null
  651 + * ArrayUtils.add(array1, null) = copy of array1
  652 + * ArrayUtils.add(null, array2) = copy of array2
  653 + * ArrayUtils.add([], []) = []
  654 + * ArrayUtils.add([null], [null]) = [null, null]
  655 + * ArrayUtils.add(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
  656 + * </pre>
  657 + *
  658 + * @param array1 the first array whose elements are added to the new array, may be <code>null</code>
  659 + * @param array2 the second array whose elements are added to the new array, may be <code>null</code>
  660 + * @return The new array, <code>null</code> if <code>null</code> array inputs.
  661 + * The type of the new array is the type of the first array.
  662 + */
  663 + public static <T> T[] add(T[] array1, T[] array2) {
  664 + return (T[]) realAddArr(array1, array2);
  665 + }
  666 +
  667 + public static boolean[] add(boolean[] array1, boolean[] array2) {
  668 + return (boolean[]) realAddArr(array1, array2);
  669 + }
  670 +
  671 + public static char[] add(char[] array1, char[] array2) {
  672 + return (char[]) realAddArr(array1, array2);
  673 + }
  674 +
  675 + public static byte[] add(byte[] array1, byte[] array2) {
  676 + return (byte[]) realAddArr(array1, array2);
  677 + }
  678 +
  679 + public static short[] add(short[] array1, short[] array2) {
  680 + return (short[]) realAddArr(array1, array2);
  681 + }
  682 +
  683 + public static int[] add(int[] array1, int[] array2) {
  684 + return (int[]) realAddArr(array1, array2);
  685 + }
  686 +
  687 + public static long[] add(long[] array1, long[] array2) {
  688 + return (long[]) realAddArr(array1, array2);
  689 + }
  690 +
  691 + public static float[] add(float[] array1, float[] array2) {
  692 + return (float[]) realAddArr(array1, array2);
  693 + }
  694 +
  695 + public static double[] add(double[] array1, double[] array2) {
  696 + return (double[]) realAddArr(array1, array2);
  697 + }
  698 +
  699 + private static Object realAddArr(Object array1, Object array2) {
  700 + if (array1 == null && array2 == null) return null;
  701 + if (array1 == null) {
  702 + return realCopy(array2);
  703 + }
  704 + if (array2 == null) {
  705 + return realCopy(array1);
  706 + }
  707 + int len1 = getLength(array1);
  708 + int len2 = getLength(array2);
  709 + Object joinedArray = Array.newInstance(array1.getClass().getComponentType(), len1 + len2);
  710 + System.arraycopy(array1, 0, joinedArray, 0, len1);
  711 + System.arraycopy(array2, 0, joinedArray, len1, len2);
  712 + return joinedArray;
  713 + }
  714 +
  715 + /**
  716 + * <p>Inserts the specified element at the specified position in the array.
  717 + * Shifts the element currently at that position (if any) and any subsequent
  718 + * elements to the right (adds one to their indices).</p>
  719 + *
  720 + * <p>This method returns a new array with the same elements of the input
  721 + * array plus the given element on the specified position. The component
  722 + * type of the returned array is always the same as that of the input
  723 + * array.</p>
  724 + *
  725 + * <p>If the input array is <code>null</code>, a new one element array is returned
  726 + * whose component type is the same as the element.</p>
  727 + *
  728 + * <pre>
  729 + * ArrayUtils.add(null, 0, null) = [null]
  730 + * ArrayUtils.add(null, 0, "a") = ["a"]
  731 + * ArrayUtils.add(["a"], 1, null) = ["a", null]
  732 + * ArrayUtils.add(["a"], 1, "b") = ["a", "b"]
  733 + * ArrayUtils.add(["a", "b"], 3, "c") = ["a", "b", "c"]
  734 + * </pre>
  735 + *
  736 + * @param array1 the array to realAdd the element to, may be <code>null</code>
  737 + * @param index the position of the new object
  738 + * @param array2 the array to realAdd
  739 + * @return A new array containing the existing elements and the new element
  740 + * @throws IndexOutOfBoundsException if the index is out of range
  741 + * (index < 0 || index > array.length).
  742 + */
  743 + public static <T> T[] add(T[] array1, int index, T[] array2) {
  744 + Class clss;
  745 + if (array1 != null) {
  746 + clss = array1.getClass().getComponentType();
  747 + } else if (array2 != null) {
  748 + clss = array2.getClass().getComponentType();
  749 + } else {
  750 + return (T[]) new Object[]{null};
  751 + }
  752 + return (T[]) realAddArr(array1, index, array2, clss);
  753 + }
  754 +
  755 + public static boolean[] add(boolean[] array1, int index, boolean[] array2) {
  756 + return (boolean[]) realAddArr(array1, index, array2, Boolean.TYPE);
  757 + }
  758 +
  759 + public static char[] add(char[] array1, int index, char[] array2) {
  760 + return (char[]) realAddArr(array1, index, array2, Character.TYPE);
  761 + }
  762 +
  763 + public static byte[] add(byte[] array1, int index, byte[] array2) {
  764 + return (byte[]) realAddArr(array1, index, array2, Byte.TYPE);
  765 + }
  766 +
  767 + public static short[] add(short[] array1, int index, short[] array2) {
  768 + return (short[]) realAddArr(array1, index, array2, Short.TYPE);
  769 + }
  770 +
  771 + public static int[] add(int[] array1, int index, int[] array2) {
  772 + return (int[]) realAddArr(array1, index, array2, Integer.TYPE);
  773 + }
  774 +
  775 + public static long[] add(long[] array1, int index, long[] array2) {
  776 + return (long[]) realAddArr(array1, index, array2, Long.TYPE);
  777 + }
  778 +
  779 + public static float[] add(float[] array1, int index, float[] array2) {
  780 + return (float[]) realAddArr(array1, index, array2, Float.TYPE);
  781 + }
  782 +
  783 + public static double[] add(double[] array1, int index, double[] array2) {
  784 + return (double[]) realAddArr(array1, index, array2, Double.TYPE);
  785 + }
  786 +
  787 + private static Object realAddArr(Object array1, int index, Object array2, Class clss) {
  788 + if (array1 == null && array2 == null) return null;
  789 + int len1 = getLength(array1);
  790 + int len2 = getLength(array2);
  791 + if (len1 == 0) {
  792 + if (index != 0) {
  793 + throw new IndexOutOfBoundsException("Index: " + index + ", array1 Length: 0");
  794 + }
  795 + return realCopy(array2);
  796 + }
  797 + if (len2 == 0) {
  798 + return realCopy(array1);
  799 + }
  800 + if (index > len1 || index < 0) {
  801 + throw new IndexOutOfBoundsException("Index: " + index + ", array1 Length: " + len1);
  802 + }
  803 + Object joinedArray = Array.newInstance(array1.getClass().getComponentType(), len1 + len2);
  804 + if (index == len1) {
  805 + System.arraycopy(array1, 0, joinedArray, 0, len1);
  806 + System.arraycopy(array2, 0, joinedArray, len1, len2);
  807 + } else if (index == 0) {
  808 + System.arraycopy(array2, 0, joinedArray, 0, len2);
  809 + System.arraycopy(array1, 0, joinedArray, len2, len1);
  810 + } else {
  811 + System.arraycopy(array1, 0, joinedArray, 0, index);
  812 + System.arraycopy(array2, 0, joinedArray, index, len2);
  813 + System.arraycopy(array1, index, joinedArray, index + len2, len1 - index);
  814 + }
  815 + return joinedArray;
  816 + }
  817 +
  818 + /**
  819 + * <p>Inserts the specified element at the specified position in the array.
  820 + * Shifts the element currently at that position (if any) and any subsequent
  821 + * elements to the right (adds one to their indices).</p>
  822 + *
  823 + * <p>This method returns a new array with the same elements of the input
  824 + * array plus the given element on the specified position. The component
  825 + * type of the returned array is always the same as that of the input
  826 + * array.</p>
  827 + *
  828 + * <p>If the input array is <code>null</code>, a new one element array is returned
  829 + * whose component type is the same as the element.</p>
  830 + *
  831 + * <pre>
  832 + * ArrayUtils.add(null, 0, null) = [null]
  833 + * ArrayUtils.add(null, 0, "a") = ["a"]
  834 + * ArrayUtils.add(["a"], 1, null) = ["a", null]
  835 + * ArrayUtils.add(["a"], 1, "b") = ["a", "b"]
  836 + * ArrayUtils.add(["a", "b"], 3, "c") = ["a", "b", "c"]
  837 + * </pre>
  838 + *
  839 + * @param array the array to realAdd the element to, may be <code>null</code>
  840 + * @param index the position of the new object
  841 + * @param element the object to realAdd
  842 + * @return A new array containing the existing elements and the new element
  843 + * @throws IndexOutOfBoundsException if the index is out of range
  844 + * (index < 0 || index > array.length).
  845 + */
  846 + public static <T> T[] add(T[] array, int index, T element) {
  847 + Class clss;
  848 + if (array != null) {
  849 + clss = array.getClass().getComponentType();
  850 + } else if (element != null) {
  851 + clss = element.getClass();
  852 + } else {
  853 + return (T[]) new Object[]{null};
  854 + }
  855 + return (T[]) realAdd(array, index, element, clss);
  856 + }
  857 +
  858 + public static boolean[] add(boolean[] array, int index, boolean element) {
  859 + return (boolean[]) realAdd(array, index, element, Boolean.TYPE);
  860 + }
  861 +
  862 + public static char[] add(char[] array, int index, char element) {
  863 + return (char[]) realAdd(array, index, element, Character.TYPE);
  864 + }
  865 +
  866 + public static byte[] add(byte[] array, int index, byte element) {
  867 + return (byte[]) realAdd(array, index, element, Byte.TYPE);
  868 + }
  869 +
  870 + public static short[] add(short[] array, int index, short element) {
  871 + return (short[]) realAdd(array, index, element, Short.TYPE);
  872 + }
  873 +
  874 + public static int[] add(int[] array, int index, int element) {
  875 + return (int[]) realAdd(array, index, element, Integer.TYPE);
  876 + }
  877 +
  878 + public static long[] add(long[] array, int index, long element) {
  879 + return (long[]) realAdd(array, index, element, Long.TYPE);
  880 + }
  881 +
  882 + public static float[] add(float[] array, int index, float element) {
  883 + return (float[]) realAdd(array, index, element, Float.TYPE);
  884 + }
  885 +
  886 + public static double[] add(double[] array, int index, double element) {
  887 + return (double[]) realAdd(array, index, element, Double.TYPE);
  888 + }
  889 +
  890 + private static Object realAdd(Object array, int index, Object element, Class clss) {
  891 + if (array == null) {
  892 + if (index != 0) {
  893 + throw new IndexOutOfBoundsException("Index: " + index + ", Length: 0");
  894 + }
  895 + Object joinedArray = Array.newInstance(clss, 1);
  896 + Array.set(joinedArray, 0, element);
  897 + return joinedArray;
  898 + }
  899 + int length = Array.getLength(array);
  900 + if (index > length || index < 0) {
  901 + throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
  902 + }
  903 + Object result = Array.newInstance(clss, length + 1);
  904 + System.arraycopy(array, 0, result, 0, index);
  905 + Array.set(result, index, element);
  906 + if (index < length) {
  907 + System.arraycopy(array, index, result, index + 1, length - index);
  908 + }
  909 + return result;
  910 + }
  911 +
  912 + ///////////////////////////////////////////////////////////////////////////
  913 + // remove
  914 + ///////////////////////////////////////////////////////////////////////////
  915 +
  916 + /**
  917 + * 移除指定的索引
  918 + * <p>Removes the element at the specified position from the specified array.
  919 + * All subsequent elements are shifted to the left (substracts one from
  920 + * their indices).</p>
  921 + *
  922 + * <p>This method returns a new array with the same elements of the input
  923 + * array except the element on the specified position. The component
  924 + * type of the returned array is always the same as that of the input
  925 + * array.</p>
  926 + *
  927 + * <p>If the input array is <code>null</code>, an IndexOutOfBoundsException
  928 + * will be thrown, because in that case no valid index can be specified.</p>
  929 + *
  930 + * <pre>
  931 + * ArrayUtils.remove(["a"], 0) = []
  932 + * ArrayUtils.remove(["a", "b"], 0) = ["b"]
  933 + * ArrayUtils.remove(["a", "b"], 1) = ["a"]
  934 + * ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"]
  935 + * </pre>
  936 + *
  937 + * @param array the array to remove the element from, may not be <code>null</code>
  938 + * @param index the position of the element to be removed
  939 + * @return A new array containing the existing elements except the element
  940 + * at the specified position.
  941 + * @throws IndexOutOfBoundsException if the index is out of range
  942 + * (index < 0 || index >= array.length), or if the array is <code>null</code>.
  943 + * @since 2.1
  944 + */
  945 + public static Object[] remove(Object[] array, int index) {
  946 + return (Object[]) remove((Object) array, index);
  947 + }
  948 +
  949 + /**
  950 + * 移除指定的元素
  951 + * <p>Removes the first occurrence of the specified element from the
  952 + * specified array. All subsequent elements are shifted to the left
  953 + * (substracts one from their indices). If the array doesn't contains
  954 + * such an element, no elements are removed from the array.</p>
  955 + *
  956 + * <p>This method returns a new array with the same elements of the input
  957 + * array except the first occurrence of the specified element. The component
  958 + * type of the returned array is always the same as that of the input
  959 + * array.</p>
  960 + *
  961 + * <pre>
  962 + * ArrayUtils.removeElement(null, "a") = null
  963 + * ArrayUtils.removeElement([], "a") = []
  964 + * ArrayUtils.removeElement(["a"], "b") = ["a"]
  965 + * ArrayUtils.removeElement(["a", "b"], "a") = ["b"]
  966 + * ArrayUtils.removeElement(["a", "b", "a"], "a") = ["b", "a"]
  967 + * </pre>
  968 + *
  969 + * @param array the array to remove the element from, may be <code>null</code>
  970 + * @param element the element to be removed
  971 + * @return A new array containing the existing elements except the first
  972 + * occurrence of the specified element.
  973 + * @since 2.1
  974 + */
  975 + public static Object[] removeElement(Object[] array, Object element) {
  976 + int index = indexOf(array, element);
  977 + if (index == INDEX_NOT_FOUND) {
  978 + return copy(array);
  979 + }
  980 + return remove(array, index);
  981 + }
  982 +
  983 + public static boolean[] remove(boolean[] array, int index) {
  984 + return (boolean[]) remove((Object) array, index);
  985 + }
  986 +
  987 + public static boolean[] removeElement(boolean[] array, boolean element) {
  988 + int index = indexOf(array, element);
  989 + if (index == INDEX_NOT_FOUND) {
  990 + return copy(array);
  991 + }
  992 + return remove(array, index);
  993 + }
  994 +
  995 + public static byte[] remove(byte[] array, int index) {
  996 + return (byte[]) remove((Object) array, index);
  997 + }
  998 +
  999 + public static byte[] removeElement(byte[] array, byte element) {
  1000 + int index = indexOf(array, element);
  1001 + if (index == INDEX_NOT_FOUND) {
  1002 + return copy(array);
  1003 + }
  1004 + return remove(array, index);
  1005 + }
  1006 +
  1007 + public static char[] remove(char[] array, int index) {
  1008 + return (char[]) remove((Object) array, index);
  1009 + }
  1010 +
  1011 + public static char[] removeElement(char[] array, char element) {
  1012 + int index = indexOf(array, element);
  1013 + if (index == INDEX_NOT_FOUND) {
  1014 + return copy(array);
  1015 + }
  1016 + return remove(array, index);
  1017 + }
  1018 +
  1019 + public static double[] remove(double[] array, int index) {
  1020 + return (double[]) remove((Object) array, index);
  1021 + }
  1022 +
  1023 + public static double[] removeElement(double[] array, double element) {
  1024 + int index = indexOf(array, element);
  1025 + if (index == INDEX_NOT_FOUND) {
  1026 + return copy(array);
  1027 + }
  1028 + return remove(array, index);
  1029 + }
  1030 +
  1031 + public static float[] remove(float[] array, int index) {
  1032 + return (float[]) remove((Object) array, index);
  1033 + }
  1034 +
  1035 + public static float[] removeElement(float[] array, float element) {
  1036 + int index = indexOf(array, element);
  1037 + if (index == INDEX_NOT_FOUND) {
  1038 + return copy(array);
  1039 + }
  1040 + return remove(array, index);
  1041 + }
  1042 +
  1043 + public static int[] remove(int[] array, int index) {
  1044 + return (int[]) remove((Object) array, index);
  1045 + }
  1046 +
  1047 + public static int[] removeElement(int[] array, int element) {
  1048 + int index = indexOf(array, element);
  1049 + if (index == INDEX_NOT_FOUND) {
  1050 + return copy(array);
  1051 + }
  1052 + return remove(array, index);
  1053 + }
  1054 +
  1055 + public static long[] remove(long[] array, int index) {
  1056 + return (long[]) remove((Object) array, index);
  1057 + }
  1058 +
  1059 + public static long[] removeElement(long[] array, long element) {
  1060 + int index = indexOf(array, element);
  1061 + if (index == INDEX_NOT_FOUND) {
  1062 + return copy(array);
  1063 + }
  1064 + return remove(array, index);
  1065 + }
  1066 +
  1067 + public static short[] remove(short[] array, int index) {
  1068 + return (short[]) remove((Object) array, index);
  1069 + }
  1070 +
  1071 + public static short[] removeElement(short[] array, short element) {
  1072 + int index = indexOf(array, element);
  1073 + if (index == INDEX_NOT_FOUND) {
  1074 + return copy(array);
  1075 + }
  1076 + return remove(array, index);
  1077 + }
  1078 +
  1079 + private static Object remove(Object array, int index) {
  1080 + int length = getLength(array);
  1081 + if (index < 0 || index >= length) {
  1082 + throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
  1083 + }
  1084 +
  1085 + Object result = Array.newInstance(array.getClass().getComponentType(), length - 1);
  1086 + System.arraycopy(array, 0, result, 0, index);
  1087 + if (index < length - 1) {
  1088 + System.arraycopy(array, index + 1, result, index, length - index - 1);
  1089 + }
  1090 +
  1091 + return result;
  1092 + }
  1093 +
  1094 + ///////////////////////////////////////////////////////////////////////////
  1095 + // object indexOf
  1096 + ///////////////////////////////////////////////////////////////////////////
  1097 +
  1098 + /**
  1099 + * 查找第一个元素的索引
  1100 + *
  1101 + * @param array
  1102 + * @param objectToFind
  1103 + * @return
  1104 + */
  1105 + public static int indexOf(Object[] array, Object objectToFind) {
  1106 + return indexOf(array, objectToFind, 0);
  1107 + }
  1108 +
  1109 + public static int indexOf(Object[] array, final Object objectToFind, int startIndex) {
  1110 + if (array == null) {
  1111 + return INDEX_NOT_FOUND;
  1112 + }
  1113 + if (startIndex < 0) {
  1114 + startIndex = 0;
  1115 + }
  1116 + if (objectToFind == null) {
  1117 + for (int i = startIndex; i < array.length; i++) {
  1118 + if (array[i] == null) {
  1119 + return i;
  1120 + }
  1121 + }
  1122 + } else {
  1123 + for (int i = startIndex; i < array.length; i++) {
  1124 + if (objectToFind.equals(array[i])) {
  1125 + return i;
  1126 + }
  1127 + }
  1128 + }
  1129 + return INDEX_NOT_FOUND;
  1130 + }
  1131 +
  1132 + /**
  1133 + * 查找最后一个元素的索引
  1134 + *
  1135 + * @param array
  1136 + * @param objectToFind
  1137 + * @return
  1138 + */
  1139 + public static int lastIndexOf(Object[] array, Object objectToFind) {
  1140 + return lastIndexOf(array, objectToFind, Integer.MAX_VALUE);
  1141 + }
  1142 +
  1143 + public static int lastIndexOf(Object[] array, Object objectToFind, int startIndex) {
  1144 + if (array == null) {
  1145 + return INDEX_NOT_FOUND;
  1146 + }
  1147 + if (startIndex < 0) {
  1148 + return INDEX_NOT_FOUND;
  1149 + } else if (startIndex >= array.length) {
  1150 + startIndex = array.length - 1;
  1151 + }
  1152 + if (objectToFind == null) {
  1153 + for (int i = startIndex; i >= 0; i--) {
  1154 + if (array[i] == null) {
  1155 + return i;
  1156 + }
  1157 + }
  1158 + } else {
  1159 + for (int i = startIndex; i >= 0; i--) {
  1160 + if (objectToFind.equals(array[i])) {
  1161 + return i;
  1162 + }
  1163 + }
  1164 + }
  1165 + return INDEX_NOT_FOUND;
  1166 + }
  1167 +
  1168 + /**
  1169 + * 判断是否包含该元素
  1170 + *
  1171 + * @param array
  1172 + * @param objectToFind
  1173 + * @return
  1174 + */
  1175 + public static boolean contains(Object[] array, Object objectToFind) {
  1176 + return indexOf(array, objectToFind) != INDEX_NOT_FOUND;
  1177 + }
  1178 +
  1179 + ///////////////////////////////////////////////////////////////////////////
  1180 + // long indexOf
  1181 + ///////////////////////////////////////////////////////////////////////////
  1182 +
  1183 + public static int indexOf(long[] array, long valueToFind) {
  1184 + return indexOf(array, valueToFind, 0);
  1185 + }
  1186 +
  1187 + public static int indexOf(long[] array, long valueToFind, int startIndex) {
  1188 + if (array == null) {
  1189 + return INDEX_NOT_FOUND;
  1190 + }
  1191 + if (startIndex < 0) {
  1192 + startIndex = 0;
  1193 + }
  1194 + for (int i = startIndex; i < array.length; i++) {
  1195 + if (valueToFind == array[i]) {
  1196 + return i;
  1197 + }
  1198 + }
  1199 + return INDEX_NOT_FOUND;
  1200 + }
  1201 +
  1202 + public static int lastIndexOf(long[] array, long valueToFind) {
  1203 + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  1204 + }
  1205 +
  1206 + public static int lastIndexOf(long[] array, long valueToFind, int startIndex) {
  1207 + if (array == null) {
  1208 + return INDEX_NOT_FOUND;
  1209 + }
  1210 + if (startIndex < 0) {
  1211 + return INDEX_NOT_FOUND;
  1212 + } else if (startIndex >= array.length) {
  1213 + startIndex = array.length - 1;
  1214 + }
  1215 + for (int i = startIndex; i >= 0; i--) {
  1216 + if (valueToFind == array[i]) {
  1217 + return i;
  1218 + }
  1219 + }
  1220 + return INDEX_NOT_FOUND;
  1221 + }
  1222 +
  1223 + public static boolean contains(long[] array, long valueToFind) {
  1224 + return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1225 + }
  1226 +
  1227 + ///////////////////////////////////////////////////////////////////////////
  1228 + // int indexOf
  1229 + ///////////////////////////////////////////////////////////////////////////
  1230 +
  1231 + public static int indexOf(int[] array, int valueToFind) {
  1232 + return indexOf(array, valueToFind, 0);
  1233 + }
  1234 +
  1235 + public static int indexOf(int[] array, int valueToFind, int startIndex) {
  1236 + if (array == null) {
  1237 + return INDEX_NOT_FOUND;
  1238 + }
  1239 + if (startIndex < 0) {
  1240 + startIndex = 0;
  1241 + }
  1242 + for (int i = startIndex; i < array.length; i++) {
  1243 + if (valueToFind == array[i]) {
  1244 + return i;
  1245 + }
  1246 + }
  1247 + return INDEX_NOT_FOUND;
  1248 + }
  1249 +
  1250 + public static int lastIndexOf(int[] array, int valueToFind) {
  1251 + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  1252 + }
  1253 +
  1254 + public static int lastIndexOf(int[] array, int valueToFind, int startIndex) {
  1255 + if (array == null) {
  1256 + return INDEX_NOT_FOUND;
  1257 + }
  1258 + if (startIndex < 0) {
  1259 + return INDEX_NOT_FOUND;
  1260 + } else if (startIndex >= array.length) {
  1261 + startIndex = array.length - 1;
  1262 + }
  1263 + for (int i = startIndex; i >= 0; i--) {
  1264 + if (valueToFind == array[i]) {
  1265 + return i;
  1266 + }
  1267 + }
  1268 + return INDEX_NOT_FOUND;
  1269 + }
  1270 +
  1271 + public static boolean contains(int[] array, int valueToFind) {
  1272 + return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1273 + }
  1274 +
  1275 + ///////////////////////////////////////////////////////////////////////////
  1276 + // short indexOf
  1277 + ///////////////////////////////////////////////////////////////////////////
  1278 +
  1279 + public static int indexOf(short[] array, short valueToFind) {
  1280 + return indexOf(array, valueToFind, 0);
  1281 + }
  1282 +
  1283 + public static int indexOf(short[] array, short valueToFind, int startIndex) {
  1284 + if (array == null) {
  1285 + return INDEX_NOT_FOUND;
  1286 + }
  1287 + if (startIndex < 0) {
  1288 + startIndex = 0;
  1289 + }
  1290 + for (int i = startIndex; i < array.length; i++) {
  1291 + if (valueToFind == array[i]) {
  1292 + return i;
  1293 + }
  1294 + }
  1295 + return INDEX_NOT_FOUND;
  1296 + }
  1297 +
  1298 + public static int lastIndexOf(short[] array, short valueToFind) {
  1299 + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  1300 + }
  1301 +
  1302 + public static int lastIndexOf(short[] array, short valueToFind, int startIndex) {
  1303 + if (array == null) {
  1304 + return INDEX_NOT_FOUND;
  1305 + }
  1306 + if (startIndex < 0) {
  1307 + return INDEX_NOT_FOUND;
  1308 + } else if (startIndex >= array.length) {
  1309 + startIndex = array.length - 1;
  1310 + }
  1311 + for (int i = startIndex; i >= 0; i--) {
  1312 + if (valueToFind == array[i]) {
  1313 + return i;
  1314 + }
  1315 + }
  1316 + return INDEX_NOT_FOUND;
  1317 + }
  1318 +
  1319 + public static boolean contains(short[] array, short valueToFind) {
  1320 + return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1321 + }
  1322 +
  1323 + ///////////////////////////////////////////////////////////////////////////
  1324 + // char indexOf
  1325 + ///////////////////////////////////////////////////////////////////////////
  1326 +
  1327 + public static int indexOf(char[] array, char valueToFind) {
  1328 + return indexOf(array, valueToFind, 0);
  1329 + }
  1330 +
  1331 + public static int indexOf(char[] array, char valueToFind, int startIndex) {
  1332 + if (array == null) {
  1333 + return INDEX_NOT_FOUND;
  1334 + }
  1335 + if (startIndex < 0) {
  1336 + startIndex = 0;
  1337 + }
  1338 + for (int i = startIndex; i < array.length; i++) {
  1339 + if (valueToFind == array[i]) {
  1340 + return i;
  1341 + }
  1342 + }
  1343 + return INDEX_NOT_FOUND;
  1344 + }
  1345 +
  1346 + public static int lastIndexOf(char[] array, char valueToFind) {
  1347 + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  1348 + }
  1349 +
  1350 + public static int lastIndexOf(char[] array, char valueToFind, int startIndex) {
  1351 + if (array == null) {
  1352 + return INDEX_NOT_FOUND;
  1353 + }
  1354 + if (startIndex < 0) {
  1355 + return INDEX_NOT_FOUND;
  1356 + } else if (startIndex >= array.length) {
  1357 + startIndex = array.length - 1;
  1358 + }
  1359 + for (int i = startIndex; i >= 0; i--) {
  1360 + if (valueToFind == array[i]) {
  1361 + return i;
  1362 + }
  1363 + }
  1364 + return INDEX_NOT_FOUND;
  1365 + }
  1366 +
  1367 + public static boolean contains(char[] array, char valueToFind) {
  1368 + return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1369 + }
  1370 +
  1371 + ///////////////////////////////////////////////////////////////////////////
  1372 + // byte indexOf
  1373 + ///////////////////////////////////////////////////////////////////////////
  1374 +
  1375 + public static int indexOf(byte[] array, byte valueToFind) {
  1376 + return indexOf(array, valueToFind, 0);
  1377 + }
  1378 +
  1379 + public static int indexOf(byte[] array, byte valueToFind, int startIndex) {
  1380 + if (array == null) {
  1381 + return INDEX_NOT_FOUND;
  1382 + }
  1383 + if (startIndex < 0) {
  1384 + startIndex = 0;
  1385 + }
  1386 + for (int i = startIndex; i < array.length; i++) {
  1387 + if (valueToFind == array[i]) {
  1388 + return i;
  1389 + }
  1390 + }
  1391 + return INDEX_NOT_FOUND;
  1392 + }
  1393 +
  1394 + public static int lastIndexOf(byte[] array, byte valueToFind) {
  1395 + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  1396 + }
  1397 +
  1398 + public static int lastIndexOf(byte[] array, byte valueToFind, int startIndex) {
  1399 + if (array == null) {
  1400 + return INDEX_NOT_FOUND;
  1401 + }
  1402 + if (startIndex < 0) {
  1403 + return INDEX_NOT_FOUND;
  1404 + } else if (startIndex >= array.length) {
  1405 + startIndex = array.length - 1;
  1406 + }
  1407 + for (int i = startIndex; i >= 0; i--) {
  1408 + if (valueToFind == array[i]) {
  1409 + return i;
  1410 + }
  1411 + }
  1412 + return INDEX_NOT_FOUND;
  1413 + }
  1414 +
  1415 + public static boolean contains(byte[] array, byte valueToFind) {
  1416 + return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1417 + }
  1418 +
  1419 + ///////////////////////////////////////////////////////////////////////////
  1420 + // double indexOf
  1421 + ///////////////////////////////////////////////////////////////////////////
  1422 +
  1423 + public static int indexOf(double[] array, double valueToFind) {
  1424 + return indexOf(array, valueToFind, 0);
  1425 + }
  1426 +
  1427 + public static int indexOf(double[] array, double valueToFind, double tolerance) {
  1428 + return indexOf(array, valueToFind, 0, tolerance);
  1429 + }
  1430 +
  1431 + public static int indexOf(double[] array, double valueToFind, int startIndex) {
  1432 + if (ArrayUtils.isEmpty(array)) {
  1433 + return INDEX_NOT_FOUND;
  1434 + }
  1435 + if (startIndex < 0) {
  1436 + startIndex = 0;
  1437 + }
  1438 + for (int i = startIndex; i < array.length; i++) {
  1439 + if (valueToFind == array[i]) {
  1440 + return i;
  1441 + }
  1442 + }
  1443 + return INDEX_NOT_FOUND;
  1444 + }
  1445 +
  1446 + public static int indexOf(double[] array, double valueToFind, int startIndex, double tolerance) {
  1447 + if (ArrayUtils.isEmpty(array)) {
  1448 + return INDEX_NOT_FOUND;
  1449 + }
  1450 + if (startIndex < 0) {
  1451 + startIndex = 0;
  1452 + }
  1453 + double min = valueToFind - tolerance;
  1454 + double max = valueToFind + tolerance;
  1455 + for (int i = startIndex; i < array.length; i++) {
  1456 + if (array[i] >= min && array[i] <= max) {
  1457 + return i;
  1458 + }
  1459 + }
  1460 + return INDEX_NOT_FOUND;
  1461 + }
  1462 +
  1463 + public static int lastIndexOf(double[] array, double valueToFind) {
  1464 + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  1465 + }
  1466 +
  1467 + public static int lastIndexOf(double[] array, double valueToFind, double tolerance) {
  1468 + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE, tolerance);
  1469 + }
  1470 +
  1471 + public static int lastIndexOf(double[] array, double valueToFind, int startIndex) {
  1472 + if (ArrayUtils.isEmpty(array)) {
  1473 + return INDEX_NOT_FOUND;
  1474 + }
  1475 + if (startIndex < 0) {
  1476 + return INDEX_NOT_FOUND;
  1477 + } else if (startIndex >= array.length) {
  1478 + startIndex = array.length - 1;
  1479 + }
  1480 + for (int i = startIndex; i >= 0; i--) {
  1481 + if (valueToFind == array[i]) {
  1482 + return i;
  1483 + }
  1484 + }
  1485 + return INDEX_NOT_FOUND;
  1486 + }
  1487 +
  1488 + public static int lastIndexOf(double[] array, double valueToFind, int startIndex, double tolerance) {
  1489 + if (ArrayUtils.isEmpty(array)) {
  1490 + return INDEX_NOT_FOUND;
  1491 + }
  1492 + if (startIndex < 0) {
  1493 + return INDEX_NOT_FOUND;
  1494 + } else if (startIndex >= array.length) {
  1495 + startIndex = array.length - 1;
  1496 + }
  1497 + double min = valueToFind - tolerance;
  1498 + double max = valueToFind + tolerance;
  1499 + for (int i = startIndex; i >= 0; i--) {
  1500 + if (array[i] >= min && array[i] <= max) {
  1501 + return i;
  1502 + }
  1503 + }
  1504 + return INDEX_NOT_FOUND;
  1505 + }
  1506 +
  1507 + public static boolean contains(double[] array, double valueToFind) {
  1508 + return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1509 + }
  1510 +
  1511 + public static boolean contains(double[] array, double valueToFind, double tolerance) {
  1512 + return indexOf(array, valueToFind, 0, tolerance) != INDEX_NOT_FOUND;
  1513 + }
  1514 +
  1515 + ///////////////////////////////////////////////////////////////////////////
  1516 + // float indexOf
  1517 + ///////////////////////////////////////////////////////////////////////////
  1518 +
  1519 + public static int indexOf(float[] array, float valueToFind) {
  1520 + return indexOf(array, valueToFind, 0);
  1521 + }
  1522 +
  1523 + public static int indexOf(float[] array, float valueToFind, int startIndex) {
  1524 + if (ArrayUtils.isEmpty(array)) {
  1525 + return INDEX_NOT_FOUND;
  1526 + }
  1527 + if (startIndex < 0) {
  1528 + startIndex = 0;
  1529 + }
  1530 + for (int i = startIndex; i < array.length; i++) {
  1531 + if (valueToFind == array[i]) {
  1532 + return i;
  1533 + }
  1534 + }
  1535 + return INDEX_NOT_FOUND;
  1536 + }
  1537 +
  1538 + public static int lastIndexOf(float[] array, float valueToFind) {
  1539 + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  1540 + }
  1541 +
  1542 + public static int lastIndexOf(float[] array, float valueToFind, int startIndex) {
  1543 + if (ArrayUtils.isEmpty(array)) {
  1544 + return INDEX_NOT_FOUND;
  1545 + }
  1546 + if (startIndex < 0) {
  1547 + return INDEX_NOT_FOUND;
  1548 + } else if (startIndex >= array.length) {
  1549 + startIndex = array.length - 1;
  1550 + }
  1551 + for (int i = startIndex; i >= 0; i--) {
  1552 + if (valueToFind == array[i]) {
  1553 + return i;
  1554 + }
  1555 + }
  1556 + return INDEX_NOT_FOUND;
  1557 + }
  1558 +
  1559 + public static boolean contains(float[] array, float valueToFind) {
  1560 + return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1561 + }
  1562 +
  1563 + ///////////////////////////////////////////////////////////////////////////
  1564 + // bool indexOf
  1565 + ///////////////////////////////////////////////////////////////////////////
  1566 +
  1567 + public static int indexOf(boolean[] array, boolean valueToFind) {
  1568 + return indexOf(array, valueToFind, 0);
  1569 + }
  1570 +
  1571 + public static int indexOf(boolean[] array, boolean valueToFind, int startIndex) {
  1572 + if (ArrayUtils.isEmpty(array)) {
  1573 + return INDEX_NOT_FOUND;
  1574 + }
  1575 + if (startIndex < 0) {
  1576 + startIndex = 0;
  1577 + }
  1578 + for (int i = startIndex; i < array.length; i++) {
  1579 + if (valueToFind == array[i]) {
  1580 + return i;
  1581 + }
  1582 + }
  1583 + return INDEX_NOT_FOUND;
  1584 + }
  1585 +
  1586 + public static int lastIndexOf(boolean[] array, boolean valueToFind) {
  1587 + return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
  1588 + }
  1589 +
  1590 + public static int lastIndexOf(boolean[] array, boolean valueToFind, int startIndex) {
  1591 + if (ArrayUtils.isEmpty(array)) {
  1592 + return INDEX_NOT_FOUND;
  1593 + }
  1594 + if (startIndex < 0) {
  1595 + return INDEX_NOT_FOUND;
  1596 + } else if (startIndex >= array.length) {
  1597 + startIndex = array.length - 1;
  1598 + }
  1599 + for (int i = startIndex; i >= 0; i--) {
  1600 + if (valueToFind == array[i]) {
  1601 + return i;
  1602 + }
  1603 + }
  1604 + return INDEX_NOT_FOUND;
  1605 + }
  1606 +
  1607 + public static boolean contains(boolean[] array, boolean valueToFind) {
  1608 + return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
  1609 + }
  1610 +
  1611 + ///////////////////////////////////////////////////////////////////////////
  1612 + // char converters
  1613 + ///////////////////////////////////////////////////////////////////////////
  1614 +
  1615 + /**
  1616 + * 装箱数组转基本类型数组
  1617 + *
  1618 + * @param array
  1619 + * @return
  1620 + */
  1621 + public static char[] toPrimitive(Character[] array) {
  1622 + if (array == null) {
  1623 + return null;
  1624 + } else if (array.length == 0) {
  1625 + return new char[0];
  1626 + }
  1627 + final char[] result = new char[array.length];
  1628 + for (int i = 0; i < array.length; i++) {
  1629 + result[i] = array[i].charValue();
  1630 + }
  1631 + return result;
  1632 + }
  1633 +
  1634 + public static char[] toPrimitive(Character[] array, char valueForNull) {
  1635 + if (array == null) {
  1636 + return null;
  1637 + } else if (array.length == 0) {
  1638 + return new char[0];
  1639 + }
  1640 + final char[] result = new char[array.length];
  1641 + for (int i = 0; i < array.length; i++) {
  1642 + Character b = array[i];
  1643 + result[i] = (b == null ? valueForNull : b.charValue());
  1644 + }
  1645 + return result;
  1646 + }
  1647 +
  1648 + /**
  1649 + * 基本类型数组转装箱数组
  1650 + *
  1651 + * @param array
  1652 + * @return
  1653 + */
  1654 + public static Character[] toObject(char[] array) {
  1655 + if (array == null) {
  1656 + return null;
  1657 + } else if (array.length == 0) {
  1658 + return new Character[0];
  1659 + }
  1660 + final Character[] result = new Character[array.length];
  1661 + for (int i = 0; i < array.length; i++) {
  1662 + result[i] = new Character(array[i]);
  1663 + }
  1664 + return result;
  1665 + }
  1666 +
  1667 + ///////////////////////////////////////////////////////////////////////////
  1668 + // long converters
  1669 + ///////////////////////////////////////////////////////////////////////////
  1670 +
  1671 + public static long[] toPrimitive(Long[] array) {
  1672 + if (array == null) {
  1673 + return null;
  1674 + } else if (array.length == 0) {
  1675 + return new long[0];
  1676 + }
  1677 + final long[] result = new long[array.length];
  1678 + for (int i = 0; i < array.length; i++) {
  1679 + result[i] = array[i].longValue();
  1680 + }
  1681 + return result;
  1682 + }
  1683 +
  1684 + public static long[] toPrimitive(Long[] array, long valueForNull) {
  1685 + if (array == null) {
  1686 + return null;
  1687 + } else if (array.length == 0) {
  1688 + return new long[0];
  1689 + }
  1690 + final long[] result = new long[array.length];
  1691 + for (int i = 0; i < array.length; i++) {
  1692 + Long b = array[i];
  1693 + result[i] = (b == null ? valueForNull : b.longValue());
  1694 + }
  1695 + return result;
  1696 + }
  1697 +
  1698 + public static Long[] toObject(long[] array) {
  1699 + if (array == null) {
  1700 + return null;
  1701 + } else if (array.length == 0) {
  1702 + return new Long[0];
  1703 + }
  1704 + final Long[] result = new Long[array.length];
  1705 + for (int i = 0; i < array.length; i++) {
  1706 + result[i] = new Long(array[i]);
  1707 + }
  1708 + return result;
  1709 + }
  1710 +
  1711 + ///////////////////////////////////////////////////////////////////////////
  1712 + // int converters
  1713 + ///////////////////////////////////////////////////////////////////////////
  1714 +
  1715 + public static int[] toPrimitive(Integer[] array) {
  1716 + if (array == null) {
  1717 + return null;
  1718 + } else if (array.length == 0) {
  1719 + return new int[0];
  1720 + }
  1721 + final int[] result = new int[array.length];
  1722 + for (int i = 0; i < array.length; i++) {
  1723 + result[i] = array[i].intValue();
  1724 + }
  1725 + return result;
  1726 + }
  1727 +
  1728 + public static int[] toPrimitive(Integer[] array, int valueForNull) {
  1729 + if (array == null) {
  1730 + return null;
  1731 + } else if (array.length == 0) {
  1732 + return new int[0];
  1733 + }
  1734 + final int[] result = new int[array.length];
  1735 + for (int i = 0; i < array.length; i++) {
  1736 + Integer b = array[i];
  1737 + result[i] = (b == null ? valueForNull : b.intValue());
  1738 + }
  1739 + return result;
  1740 + }
  1741 +
  1742 + public static Integer[] toObject(int[] array) {
  1743 + if (array == null) {
  1744 + return null;
  1745 + } else if (array.length == 0) {
  1746 + return new Integer[0];
  1747 + }
  1748 + final Integer[] result = new Integer[array.length];
  1749 + for (int i = 0; i < array.length; i++) {
  1750 + result[i] = new Integer(array[i]);
  1751 + }
  1752 + return result;
  1753 + }
  1754 +
  1755 + ///////////////////////////////////////////////////////////////////////////
  1756 + // short converters
  1757 + ///////////////////////////////////////////////////////////////////////////
  1758 +
  1759 + public static short[] toPrimitive(Short[] array) {
  1760 + if (array == null) {
  1761 + return null;
  1762 + } else if (array.length == 0) {
  1763 + return new short[0];
  1764 + }
  1765 + final short[] result = new short[array.length];
  1766 + for (int i = 0; i < array.length; i++) {
  1767 + result[i] = array[i].shortValue();
  1768 + }
  1769 + return result;
  1770 + }
  1771 +
  1772 + public static short[] toPrimitive(Short[] array, short valueForNull) {
  1773 + if (array == null) {
  1774 + return null;
  1775 + } else if (array.length == 0) {
  1776 + return new short[0];
  1777 + }
  1778 + final short[] result = new short[array.length];
  1779 + for (int i = 0; i < array.length; i++) {
  1780 + Short b = array[i];
  1781 + result[i] = (b == null ? valueForNull : b.shortValue());
  1782 + }
  1783 + return result;
  1784 + }
  1785 +
  1786 + public static Short[] toObject(short[] array) {
  1787 + if (array == null) {
  1788 + return null;
  1789 + } else if (array.length == 0) {
  1790 + return new Short[0];
  1791 + }
  1792 + final Short[] result = new Short[array.length];
  1793 + for (int i = 0; i < array.length; i++) {
  1794 + result[i] = new Short(array[i]);
  1795 + }
  1796 + return result;
  1797 + }
  1798 +
  1799 + ///////////////////////////////////////////////////////////////////////////
  1800 + // byte converters
  1801 + ///////////////////////////////////////////////////////////////////////////
  1802 +
  1803 + public static byte[] toPrimitive(Byte[] array) {
  1804 + if (array == null) {
  1805 + return null;
  1806 + } else if (array.length == 0) {
  1807 + return new byte[0];
  1808 + }
  1809 + final byte[] result = new byte[array.length];
  1810 + for (int i = 0; i < array.length; i++) {
  1811 + result[i] = array[i].byteValue();
  1812 + }
  1813 + return result;
  1814 + }
  1815 +
  1816 + public static byte[] toPrimitive(Byte[] array, byte valueForNull) {
  1817 + if (array == null) {
  1818 + return null;
  1819 + } else if (array.length == 0) {
  1820 + return new byte[0];
  1821 + }
  1822 + final byte[] result = new byte[array.length];
  1823 + for (int i = 0; i < array.length; i++) {
  1824 + Byte b = array[i];
  1825 + result[i] = (b == null ? valueForNull : b.byteValue());
  1826 + }
  1827 + return result;
  1828 + }
  1829 +
  1830 + public static Byte[] toObject(byte[] array) {
  1831 + if (array == null) {
  1832 + return null;
  1833 + } else if (array.length == 0) {
  1834 + return new Byte[0];
  1835 + }
  1836 + final Byte[] result = new Byte[array.length];
  1837 + for (int i = 0; i < array.length; i++) {
  1838 + result[i] = new Byte(array[i]);
  1839 + }
  1840 + return result;
  1841 + }
  1842 +
  1843 + ///////////////////////////////////////////////////////////////////////////
  1844 + // double converters
  1845 + ///////////////////////////////////////////////////////////////////////////
  1846 +
  1847 + public static double[] toPrimitive(Double[] array) {
  1848 + if (array == null) {
  1849 + return null;
  1850 + } else if (array.length == 0) {
  1851 + return new double[0];
  1852 + }
  1853 + final double[] result = new double[array.length];
  1854 + for (int i = 0; i < array.length; i++) {
  1855 + result[i] = array[i].doubleValue();
  1856 + }
  1857 + return result;
  1858 + }
  1859 +
  1860 + public static double[] toPrimitive(Double[] array, double valueForNull) {
  1861 + if (array == null) {
  1862 + return null;
  1863 + } else if (array.length == 0) {
  1864 + return new double[0];
  1865 + }
  1866 + final double[] result = new double[array.length];
  1867 + for (int i = 0; i < array.length; i++) {
  1868 + Double b = array[i];
  1869 + result[i] = (b == null ? valueForNull : b.doubleValue());
  1870 + }
  1871 + return result;
  1872 + }
  1873 +
  1874 + public static Double[] toObject(double[] array) {
  1875 + if (array == null) {
  1876 + return null;
  1877 + } else if (array.length == 0) {
  1878 + return new Double[0];
  1879 + }
  1880 + final Double[] result = new Double[array.length];
  1881 + for (int i = 0; i < array.length; i++) {
  1882 + result[i] = new Double(array[i]);
  1883 + }
  1884 + return result;
  1885 + }
  1886 +
  1887 + ///////////////////////////////////////////////////////////////////////////
  1888 + // float converters
  1889 + ///////////////////////////////////////////////////////////////////////////
  1890 +
  1891 + public static float[] toPrimitive(Float[] array) {
  1892 + if (array == null) {
  1893 + return null;
  1894 + } else if (array.length == 0) {
  1895 + return new float[0];
  1896 + }
  1897 + final float[] result = new float[array.length];
  1898 + for (int i = 0; i < array.length; i++) {
  1899 + result[i] = array[i].floatValue();
  1900 + }
  1901 + return result;
  1902 + }
  1903 +
  1904 + public static float[] toPrimitive(Float[] array, float valueForNull) {
  1905 + if (array == null) {
  1906 + return null;
  1907 + } else if (array.length == 0) {
  1908 + return new float[0];
  1909 + }
  1910 + final float[] result = new float[array.length];
  1911 + for (int i = 0; i < array.length; i++) {
  1912 + Float b = array[i];
  1913 + result[i] = (b == null ? valueForNull : b.floatValue());
  1914 + }
  1915 + return result;
  1916 + }
  1917 +
  1918 + public static Float[] toObject(float[] array) {
  1919 + if (array == null) {
  1920 + return null;
  1921 + } else if (array.length == 0) {
  1922 + return new Float[0];
  1923 + }
  1924 + final Float[] result = new Float[array.length];
  1925 + for (int i = 0; i < array.length; i++) {
  1926 + result[i] = new Float(array[i]);
  1927 + }
  1928 + return result;
  1929 + }
  1930 +
  1931 + ///////////////////////////////////////////////////////////////////////////
  1932 + // boolean converters
  1933 + ///////////////////////////////////////////////////////////////////////////
  1934 +
  1935 + public static boolean[] toPrimitive(Boolean[] array) {
  1936 + if (array == null) {
  1937 + return null;
  1938 + } else if (array.length == 0) {
  1939 + return new boolean[0];
  1940 + }
  1941 + final boolean[] result = new boolean[array.length];
  1942 + for (int i = 0; i < array.length; i++) {
  1943 + result[i] = array[i].booleanValue();
  1944 + }
  1945 + return result;
  1946 + }
  1947 +
  1948 + public static boolean[] toPrimitive(Boolean[] array, boolean valueForNull) {
  1949 + if (array == null) {
  1950 + return null;
  1951 + } else if (array.length == 0) {
  1952 + return new boolean[0];
  1953 + }
  1954 + final boolean[] result = new boolean[array.length];
  1955 + for (int i = 0; i < array.length; i++) {
  1956 + Boolean b = array[i];
  1957 + result[i] = (b == null ? valueForNull : b.booleanValue());
  1958 + }
  1959 + return result;
  1960 + }
  1961 +
  1962 + public static Boolean[] toObject(boolean[] array) {
  1963 + if (array == null) {
  1964 + return null;
  1965 + } else if (array.length == 0) {
  1966 + return new Boolean[0];
  1967 + }
  1968 + final Boolean[] result = new Boolean[array.length];
  1969 + for (int i = 0; i < array.length; i++) {
  1970 + result[i] = (array[i] ? Boolean.TRUE : Boolean.FALSE);
  1971 + }
  1972 + return result;
  1973 + }
  1974 +
  1975 + /**
  1976 + * 转为链表
  1977 + *
  1978 + * @param array
  1979 + * @param <T>
  1980 + * @return
  1981 + */
  1982 + public static <T> List<T> asList(T... array) {
  1983 + if (array == null || array.length == 0) {
  1984 + return Collections.emptyList();
  1985 + }
  1986 + return Arrays.asList(array);
  1987 + }
  1988 +
  1989 + /**
  1990 + * 转为不可变链表
  1991 + *
  1992 + * @param array
  1993 + * @param <T>
  1994 + * @return
  1995 + */
  1996 + public static <T> List<T> asUnmodifiableList(T... array) {
  1997 + return Collections.unmodifiableList(asList(array));
  1998 + }
  1999 +
  2000 + /**
  2001 + * 转为数组链表
  2002 + *
  2003 + * @param array
  2004 + * @param <T>
  2005 + * @return
  2006 + */
  2007 + public static <T> List<T> asArrayList(T... array) {
  2008 + List<T> list = new ArrayList<>();
  2009 + if (array == null || array.length == 0) return list;
  2010 + list.addAll(Arrays.asList(array));
  2011 + return list;
  2012 + }
  2013 +
  2014 + /**
  2015 + * 转为双向链表
  2016 + *
  2017 + * @param array
  2018 + * @param <T>
  2019 + * @return
  2020 + */
  2021 + public static <T> List<T> asLinkedList(T... array) {
  2022 + List<T> list = new LinkedList<>();
  2023 + if (array == null || array.length == 0) return list;
  2024 + list.addAll(Arrays.asList(array));
  2025 + return list;
  2026 + }
  2027 +
  2028 + /**
  2029 + * 排序
  2030 + *
  2031 + * @param array
  2032 + * @param c
  2033 + * @param <T>
  2034 + */
  2035 + public static <T> void sort(T[] array, Comparator<? super T> c) {
  2036 + if (array == null || array.length < 2) return;
  2037 + Arrays.sort(array, c);
  2038 + }
  2039 +
  2040 + public static void sort(byte[] array) {
  2041 + if (array == null || array.length < 2) return;
  2042 + Arrays.sort(array);
  2043 + }
  2044 +
  2045 + public static void sort(char[] array) {
  2046 + if (array == null || array.length < 2) return;
  2047 + Arrays.sort(array);
  2048 + }
  2049 +
  2050 + public static void sort(double[] array) {
  2051 + if (array == null || array.length < 2) return;
  2052 + Arrays.sort(array);
  2053 + }
  2054 +
  2055 + public static void sort(float[] array) {
  2056 + if (array == null || array.length < 2) return;
  2057 + Arrays.sort(array);
  2058 + }
  2059 +
  2060 + public static void sort(int[] array) {
  2061 + if (array == null || array.length < 2) return;
  2062 + Arrays.sort(array);
  2063 + }
  2064 +
  2065 + public static void sort(long[] array) {
  2066 + if (array == null || array.length < 2) return;
  2067 + Arrays.sort(array);
  2068 + }
  2069 +
  2070 + public static void sort(short[] array) {
  2071 + if (array == null || array.length < 2) return;
  2072 + Arrays.sort(array);
  2073 + }
  2074 +
  2075 + /**
  2076 + * 对所有元素做操作
  2077 + * Executes the given closure on each element in the array.
  2078 + * <p>
  2079 + * If the input array or closure is null, there is no change made.
  2080 + *
  2081 + * @param array The array.
  2082 + * @param closure the closure to perform, may be null
  2083 + */
  2084 + public static <E> void forAllDo(Object array, Closure<E> closure) {
  2085 + if (array == null || closure == null) return;
  2086 + if (array instanceof Object[]) {
  2087 + Object[] objects = (Object[]) array;
  2088 + for (int i = 0, length = objects.length; i < length; i++) {
  2089 + Object ele = objects[i];
  2090 + closure.execute(i, (E) ele);
  2091 + }
  2092 + } else if (array instanceof boolean[]) {
  2093 + boolean[] booleans = (boolean[]) array;
  2094 + for (int i = 0, length = booleans.length; i < length; i++) {
  2095 + boolean ele = booleans[i];
  2096 + closure.execute(i, (E) (ele ? Boolean.TRUE : Boolean.FALSE));
  2097 + }
  2098 + } else if (array instanceof byte[]) {
  2099 + byte[] bytes = (byte[]) array;
  2100 + for (int i = 0, length = bytes.length; i < length; i++) {
  2101 + byte ele = bytes[i];
  2102 + closure.execute(i, (E) Byte.valueOf(ele));
  2103 + }
  2104 + } else if (array instanceof char[]) {
  2105 + char[] chars = (char[]) array;
  2106 + for (int i = 0, length = chars.length; i < length; i++) {
  2107 + char ele = chars[i];
  2108 + closure.execute(i, (E) Character.valueOf(ele));
  2109 + }
  2110 + } else if (array instanceof short[]) {
  2111 + short[] shorts = (short[]) array;
  2112 + for (int i = 0, length = shorts.length; i < length; i++) {
  2113 + short ele = shorts[i];
  2114 + closure.execute(i, (E) Short.valueOf(ele));
  2115 + }
  2116 + } else if (array instanceof int[]) {
  2117 + int[] ints = (int[]) array;
  2118 + for (int i = 0, length = ints.length; i < length; i++) {
  2119 + int ele = ints[i];
  2120 + closure.execute(i, (E) Integer.valueOf(ele));
  2121 + }
  2122 + } else if (array instanceof long[]) {
  2123 + long[] longs = (long[]) array;
  2124 + for (int i = 0, length = longs.length; i < length; i++) {
  2125 + long ele = longs[i];
  2126 + closure.execute(i, (E) Long.valueOf(ele));
  2127 + }
  2128 + } else if (array instanceof float[]) {
  2129 + float[] floats = (float[]) array;
  2130 + for (int i = 0, length = floats.length; i < length; i++) {
  2131 + float ele = floats[i];
  2132 + closure.execute(i, (E) Float.valueOf(ele));
  2133 + }
  2134 + } else if (array instanceof double[]) {
  2135 + double[] doubles = (double[]) array;
  2136 + for (int i = 0, length = doubles.length; i < length; i++) {
  2137 + double ele = doubles[i];
  2138 + closure.execute(i, (E) Double.valueOf(ele));
  2139 + }
  2140 + } else {
  2141 + throw new IllegalArgumentException("Not an array: " + array.getClass());
  2142 + }
  2143 + }
  2144 +
  2145 + /**
  2146 + * 数组转为字符串
  2147 + * Return the string of array.
  2148 + *
  2149 + * @param array The array.
  2150 + * @return the string of array
  2151 + */
  2152 + public static String toString(Object array) {
  2153 + if (array == null) return "null";
  2154 + if (array instanceof Object[]) {
  2155 + return Arrays.deepToString((Object[]) array);
  2156 + } else if (array instanceof boolean[]) {
  2157 + return Arrays.toString((boolean[]) array);
  2158 + } else if (array instanceof byte[]) {
  2159 + return Arrays.toString((byte[]) array);
  2160 + } else if (array instanceof char[]) {
  2161 + return Arrays.toString((char[]) array);
  2162 + } else if (array instanceof double[]) {
  2163 + return Arrays.toString((double[]) array);
  2164 + } else if (array instanceof float[]) {
  2165 + return Arrays.toString((float[]) array);
  2166 + } else if (array instanceof int[]) {
  2167 + return Arrays.toString((int[]) array);
  2168 + } else if (array instanceof long[]) {
  2169 + return Arrays.toString((long[]) array);
  2170 + } else if (array instanceof short[]) {
  2171 + return Arrays.toString((short[]) array);
  2172 + }
  2173 + throw new IllegalArgumentException("Array has incompatible type: " + array.getClass());
  2174 + }
  2175 +
  2176 + public interface Closure<E> {
  2177 + void execute(int index, E item);
  2178 + }
  2179 +}
core/base/src/main/java/com/cnlive/core/libs/base/util/CollectionUtils.java 0 → 100644
  1 +package com.cnlive.core.libs.base.util;
  2 +
  3 +import java.lang.reflect.Array;
  4 +import java.util.ArrayList;
  5 +import java.util.Arrays;
  6 +import java.util.Collection;
  7 +import java.util.Collections;
  8 +import java.util.Comparator;
  9 +import java.util.Enumeration;
  10 +import java.util.HashMap;
  11 +import java.util.HashSet;
  12 +import java.util.Iterator;
  13 +import java.util.LinkedList;
  14 +import java.util.List;
  15 +import java.util.ListIterator;
  16 +import java.util.Map;
  17 +import java.util.Set;
  18 +import java.util.TreeSet;
  19 +
  20 +/**
  21 + * <pre>
  22 + * author: blankj
  23 + * blog : http://blankj.com
  24 + * time : 2019/07/26
  25 + * desc : utils about collection
  26 + * </pre>
  27 + * newUnmodifiableList[NotNull]: 新建只读[非空]链表
  28 + * newArrayList[NotNull] : 新建数组型[非空]链表
  29 + * newLinkedList[NotNull] : 新建指针型[非空]链表
  30 + * newHashSet[NotNull] : 新建哈希[非空]集合
  31 + * newTreeSet[NotNull] : 新建有序[非空]集合
  32 + * newSynchronizedCollection : 新建同步集合
  33 + * newUnmodifiableCollection : 新建只读集合
  34 + * union : 获取并集
  35 + * intersection : 获取交集
  36 + * disjunction : 获取并集减交集
  37 + * subtract : 获取差集
  38 + * containsAny : 判断是否有交集
  39 + * getCardinalityMap : 获取集合中所有元素的基数
  40 + * isSubCollection : 是否子集
  41 + * isProperSubCollection : 是否真子集
  42 + * isEqualCollection : 判断集合是否相等
  43 + * cardinality : 获取集合中元素的基数
  44 + * find : 查找第一个符合条件的元素
  45 + * forAllDo : 对所有元素做操作
  46 + * filter : 删除原集合中不符合条件的元素
  47 + * select : 查找出所有符合条件的元素并返回新集合
  48 + * selectRejected : 查找出所有不符合条件的元素并返回新集合
  49 + * transform : 对原集合进行转变
  50 + * collect : 转变为新的集合
  51 + * countMatches : 查找到匹配的元素个数
  52 + * exists : 判断集合是否存在符合条件的元素
  53 + * addIgnoreNull : 新增元素如果不为空
  54 + * addAll : 新增多个元素
  55 + * get : 获取集合元素
  56 + * size : 获取集合个数
  57 + * sizeIsEmpty : 判断个数是否为零
  58 + * isEmpty : 判断是否为空
  59 + * isNotEmpty : 判断是否非空
  60 + * retainAll : 保留元素
  61 + * removeAll : 删除下来
  62 + * toString : 集合转为字符串
  63 + */
  64 +public final class CollectionUtils {
  65 +
  66 + private CollectionUtils() {
  67 + throw new UnsupportedOperationException("u can't instantiate me...");
  68 + }
  69 +
  70 + ///////////////////////////////////////////////////////////////////////////
  71 + // listOf
  72 + ///////////////////////////////////////////////////////////////////////////
  73 +
  74 + /**
  75 + * 新建只读[非空]链表
  76 + * Returns a new read-only list of given elements.
  77 + *
  78 + * @param array The array.
  79 + * @return a new read-only list of given elements
  80 + */
  81 + @SafeVarargs
  82 + public static <E> List<E> newUnmodifiableList(E... array) {
  83 + return Collections.unmodifiableList(newArrayList(array));
  84 + }
  85 +
  86 + /**
  87 + * Returns a new read-only list only of those given elements, that are not null.
  88 + *
  89 + * @param array The array.
  90 + * @return a new read-only list only of those given elements, that are not null
  91 + */
  92 + @SafeVarargs
  93 + public static <E> List<E> newUnmodifiableListNotNull(E... array) {
  94 + return Collections.unmodifiableList(newArrayListNotNull(array));
  95 + }
  96 +
  97 + /**
  98 + * 新建数组型[非空]链表
  99 + *
  100 + * @param array
  101 + * @param <E>
  102 + * @return
  103 + */
  104 + @SafeVarargs
  105 + public static <E> ArrayList<E> newArrayList(E... array) {
  106 + ArrayList<E> list = new ArrayList<>();
  107 + if (array == null || array.length == 0) return list;
  108 + for (E e : array) {
  109 + list.add(e);
  110 + }
  111 + return list;
  112 + }
  113 +
  114 + @SafeVarargs
  115 + public static <E> ArrayList<E> newArrayListNotNull(E... array) {
  116 + ArrayList<E> list = new ArrayList<>();
  117 + if (array == null || array.length == 0) return list;
  118 + for (E e : array) {
  119 + if (e == null) continue;
  120 + list.add(e);
  121 + }
  122 + return list;
  123 + }
  124 +
  125 + /**
  126 + * 新建指针型[非空]链表
  127 + *
  128 + * @param array
  129 + * @param <E>
  130 + * @return
  131 + */
  132 + @SafeVarargs
  133 + public static <E> List<E> newLinkedList(E... array) {
  134 + LinkedList<E> list = new LinkedList<>();
  135 + if (array == null || array.length == 0) return list;
  136 + for (E e : array) {
  137 + list.add(e);
  138 + }
  139 + return list;
  140 + }
  141 +
  142 + @SafeVarargs
  143 + public static <E> List<E> newLinkedListNotNull(E... array) {
  144 + LinkedList<E> list = new LinkedList<>();
  145 + if (array == null || array.length == 0) return list;
  146 + for (E e : array) {
  147 + if (e == null) continue;
  148 + list.add(e);
  149 + }
  150 + return list;
  151 + }
  152 +
  153 + /**
  154 + * 新建哈希[非空]集合
  155 + *
  156 + * @param array
  157 + * @param <E>
  158 + * @return
  159 + */
  160 + @SafeVarargs
  161 + public static <E> HashSet<E> newHashSet(E... array) {
  162 + HashSet<E> set = new HashSet<>();
  163 + if (array == null || array.length == 0) return set;
  164 + for (E e : array) {
  165 + set.add(e);
  166 + }
  167 + return set;
  168 + }
  169 +
  170 + @SafeVarargs
  171 + public static <E> HashSet<E> newHashSetNotNull(E... array) {
  172 + HashSet<E> set = new HashSet<>();
  173 + if (array == null || array.length == 0) return set;
  174 + for (E e : array) {
  175 + if (e == null) continue;
  176 + set.add(e);
  177 + }
  178 + return set;
  179 + }
  180 +
  181 + /**
  182 + * 新建有序[非空]集合
  183 + *
  184 + * @param comparator
  185 + * @param array
  186 + * @param <E>
  187 + * @return
  188 + */
  189 + @SafeVarargs
  190 + public static <E> TreeSet<E> newTreeSet(Comparator<E> comparator, E... array) {
  191 + TreeSet<E> set = new TreeSet<>(comparator);
  192 + if (array == null || array.length == 0) return set;
  193 + for (E e : array) {
  194 + set.add(e);
  195 + }
  196 + return set;
  197 + }
  198 +
  199 + @SafeVarargs
  200 + public static <E> TreeSet<E> newTreeSetNotNull(Comparator<E> comparator, E... array) {
  201 + TreeSet<E> set = new TreeSet<>(comparator);
  202 + if (array == null || array.length == 0) return set;
  203 + for (E e : array) {
  204 + if (e == null) continue;
  205 + set.add(e);
  206 + }
  207 + return set;
  208 + }
  209 +
  210 + /**
  211 + * 新建同步集合
  212 + *
  213 + * @param collection
  214 + * @return
  215 + */
  216 + public static Collection newSynchronizedCollection(Collection collection) {
  217 + return Collections.synchronizedCollection(collection);
  218 + }
  219 +
  220 + /**
  221 + * 新建只读集合
  222 + *
  223 + * @param collection
  224 + * @return
  225 + */
  226 + public static Collection newUnmodifiableCollection(Collection collection) {
  227 + return Collections.unmodifiableCollection(collection);
  228 + }
  229 +
  230 + /**
  231 + * 获取并集
  232 + * Returns a {@link Collection} containing the union
  233 + * of the given {@link Collection}s.
  234 + * <p>
  235 + * The cardinality of each element in the returned {@link Collection}
  236 + * will be equal to the maximum of the cardinality of that element
  237 + * in the two given {@link Collection}s.
  238 + *
  239 + * @param a the first collection
  240 + * @param b the second collection
  241 + * @return the union of the two collections
  242 + * @see Collection#addAll
  243 + */
  244 + public static Collection union(final Collection a, final Collection b) {
  245 + if (a == null && b == null) return new ArrayList();
  246 + if (a == null) return new ArrayList<Object>(b);
  247 + if (b == null) return new ArrayList<Object>(a);
  248 + ArrayList<Object> list = new ArrayList<>();
  249 + Map<Object, Integer> mapA = getCardinalityMap(a);
  250 + Map<Object, Integer> mapB = getCardinalityMap(b);
  251 + Set<Object> elts = new HashSet<Object>(a);
  252 + elts.addAll(b);
  253 + for (Object obj : elts) {
  254 + for (int i = 0, m = Math.max(getFreq(obj, mapA), getFreq(obj, mapB)); i < m; i++) {
  255 + list.add(obj);
  256 + }
  257 + }
  258 + return list;
  259 + }
  260 +
  261 + /**
  262 + * 获取交集
  263 + * Returns a {@link Collection} containing the intersection
  264 + * of the given {@link Collection}s.
  265 + * <p>
  266 + * The cardinality of each element in the returned {@link Collection}
  267 + * will be equal to the minimum of the cardinality of that element
  268 + * in the two given {@link Collection}s.
  269 + *
  270 + * @param a the first collection
  271 + * @param b the second collection
  272 + * @return the intersection of the two collections
  273 + * @see Collection#retainAll
  274 + */
  275 + public static Collection intersection(final Collection a, final Collection b) {
  276 + if (a == null || b == null) return new ArrayList();
  277 + ArrayList<Object> list = new ArrayList<>();
  278 + Map mapA = getCardinalityMap(a);
  279 + Map mapB = getCardinalityMap(b);
  280 + Set<Object> elts = new HashSet<Object>(a);
  281 + elts.addAll(b);
  282 + for (Object obj : elts) {
  283 + for (int i = 0, m = Math.min(getFreq(obj, mapA), getFreq(obj, mapB)); i < m; i++) {
  284 + list.add(obj);
  285 + }
  286 + }
  287 + return list;
  288 + }
  289 +
  290 + private static int getFreq(final Object obj, final Map freqMap) {
  291 + Integer count = (Integer) freqMap.get(obj);
  292 + if (count != null) {
  293 + return count;
  294 + }
  295 + return 0;
  296 + }
  297 +
  298 + /**
  299 + * 获取并集减交集
  300 + * Returns a {@link Collection} containing the exclusive disjunction
  301 + * (symmetric difference) of the given {@link Collection}s.
  302 + * <p>
  303 + * The cardinality of each element <i>e</i> in the returned {@link Collection}
  304 + * will be equal to
  305 + * <tt>max(cardinality(<i>e</i>,<i>a</i>),cardinality(<i>e</i>,<i>b</i>)) - min(cardinality(<i>e</i>,<i>a</i>),cardinality(<i>e</i>,<i>b</i>))</tt>.
  306 + * <p>
  307 + * This is equivalent to
  308 + * <tt>{@link #subtract subtract}({@link #union union(a,b)},{@link #intersection intersection(a,b)})</tt>
  309 + * or
  310 + * <tt>{@link #union union}({@link #subtract subtract(a,b)},{@link #subtract subtract(b,a)})</tt>.
  311 + *
  312 + * @param a the first collection
  313 + * @param b the second collection
  314 + * @return the symmetric difference of the two collections
  315 + */
  316 + public static Collection disjunction(final Collection a, final Collection b) {
  317 + if (a == null && b == null) return new ArrayList();
  318 + if (a == null) return new ArrayList<Object>(b);
  319 + if (b == null) return new ArrayList<Object>(a);
  320 + ArrayList<Object> list = new ArrayList<>();
  321 + Map mapA = getCardinalityMap(a);
  322 + Map mapB = getCardinalityMap(b);
  323 + Set<Object> elts = new HashSet<Object>(a);
  324 + elts.addAll(b);
  325 + for (Object obj : elts) {
  326 + for (int i = 0, m = ((Math.max(getFreq(obj, mapA), getFreq(obj, mapB)))
  327 + - (Math.min(getFreq(obj, mapA), getFreq(obj, mapB)))); i < m; i++) {
  328 + list.add(obj);
  329 + }
  330 + }
  331 + return list;
  332 + }
  333 +
  334 + /**
  335 + * 获取差集
  336 + * Returns a new {@link Collection} containing <tt><i>a</i> - <i>b</i></tt>.
  337 + * The cardinality of each element <i>e</i> in the returned {@link Collection}
  338 + * will be the cardinality of <i>e</i> in <i>a</i> minus the cardinality
  339 + * of <i>e</i> in <i>b</i>, or zero, whichever is greater.
  340 + *
  341 + * @param a the collection to subtract from
  342 + * @param b the collection to subtract
  343 + * @return a new collection with the results
  344 + * @see Collection#removeAll
  345 + */
  346 + public static Collection subtract(final Collection a, final Collection b) {
  347 + if (a == null) return new ArrayList();
  348 + if (b == null) return new ArrayList<Object>(a);
  349 + ArrayList<Object> list = new ArrayList<Object>(a);
  350 + for (Object o : b) {
  351 + list.remove(o);
  352 + }
  353 + return list;
  354 + }
  355 +
  356 + /**
  357 + * 判断是否有交集
  358 + * Returns <code>true</code> iff at least one element is in both collections.
  359 + * <p>
  360 + * In other words, this method returns <code>true</code> iff the
  361 + * {@link #intersection} of <i>coll1</i> and <i>coll2</i> is not empty.
  362 + *
  363 + * @param coll1 the first collection
  364 + * @param coll2 the first collection
  365 + * @return <code>true</code> iff the intersection of the collections is non-empty
  366 + * @see #intersection
  367 + */
  368 + public static boolean containsAny(final Collection coll1, final Collection coll2) {
  369 + if (coll1 == null || coll2 == null) return false;
  370 + if (coll1.size() < coll2.size()) {
  371 + for (Object o : coll1) {
  372 + if (coll2.contains(o)) {
  373 + return true;
  374 + }
  375 + }
  376 + } else {
  377 + for (Object o : coll2) {
  378 + if (coll1.contains(o)) {
  379 + return true;
  380 + }
  381 + }
  382 + }
  383 + return false;
  384 + }
  385 +
  386 +
  387 + /**
  388 + * 获取集合中所有元素的基数
  389 + * Returns a {@link Map} mapping each unique element in the given
  390 + * {@link Collection} to an {@link Integer} representing the number
  391 + * of occurrences of that element in the {@link Collection}.
  392 + * <p>
  393 + * Only those elements present in the collection will appear as
  394 + * keys in the map.
  395 + *
  396 + * @param coll the collection to get the cardinality map for, must not be null
  397 + * @return the populated cardinality map
  398 + */
  399 + public static Map<Object, Integer> getCardinalityMap(final Collection coll) {
  400 + Map<Object, Integer> count = new HashMap<>();
  401 + if (coll == null) return count;
  402 + for (Object obj : coll) {
  403 + Integer c = count.get(obj);
  404 + if (c == null) {
  405 + count.put(obj, 1);
  406 + } else {
  407 + count.put(obj, c + 1);
  408 + }
  409 + }
  410 + return count;
  411 + }
  412 +
  413 + /**
  414 + * 是否子集
  415 + * Returns <tt>true</tt> iff <i>a</i> is a sub-collection of <i>b</i>,
  416 + * that is, iff the cardinality of <i>e</i> in <i>a</i> is less
  417 + * than or equal to the cardinality of <i>e</i> in <i>b</i>,
  418 + * for each element <i>e</i> in <i>a</i>.
  419 + *
  420 + * @param a the first (sub?) collection
  421 + * @param b the second (super?) collection
  422 + * @return <code>true</code> iff <i>a</i> is a sub-collection of <i>b</i>
  423 + * @see #isProperSubCollection
  424 + * @see Collection#containsAll
  425 + */
  426 + public static boolean isSubCollection(final Collection a, final Collection b) {
  427 + if (a == null || b == null) return false;
  428 + Map mapA = getCardinalityMap(a);
  429 + Map mapB = getCardinalityMap(b);
  430 + for (Object obj : a) {
  431 + if (getFreq(obj, mapA) > getFreq(obj, mapB)) {
  432 + return false;
  433 + }
  434 + }
  435 + return true;
  436 + }
  437 +
  438 + /**
  439 + * 是否真子集
  440 + * Returns <tt>true</tt> iff <i>a</i> is a <i>proper</i> sub-collection of <i>b</i>,
  441 + * that is, iff the cardinality of <i>e</i> in <i>a</i> is less
  442 + * than or equal to the cardinality of <i>e</i> in <i>b</i>,
  443 + * for each element <i>e</i> in <i>a</i>, and there is at least one
  444 + * element <i>f</i> such that the cardinality of <i>f</i> in <i>b</i>
  445 + * is strictly greater than the cardinality of <i>f</i> in <i>a</i>.
  446 + * <p>
  447 + * The implementation assumes
  448 + * <ul>
  449 + * <li><code>a.size()</code> and <code>b.size()</code> represent the
  450 + * total cardinality of <i>a</i> and <i>b</i>, resp. </li>
  451 + * <li><code>a.size() < Integer.MAXVALUE</code></li>
  452 + * </ul>
  453 + *
  454 + * @param a the first (sub?) collection
  455 + * @param b the second (super?) collection
  456 + * @return <code>true</code> iff <i>a</i> is a <i>proper</i> sub-collection of <i>b</i>
  457 + * @see #isSubCollection
  458 + * @see Collection#containsAll
  459 + */
  460 + public static boolean isProperSubCollection(final Collection a, final Collection b) {
  461 + if (a == null || b == null) return false;
  462 + return a.size() < b.size() && CollectionUtils.isSubCollection(a, b);
  463 + }
  464 +
  465 + /**
  466 + * 判断集合是否相等
  467 + * Returns <tt>true</tt> iff the given {@link Collection}s contain
  468 + * exactly the same elements with exactly the same cardinalities.
  469 + * <p>
  470 + * That is, iff the cardinality of <i>e</i> in <i>a</i> is
  471 + * equal to the cardinality of <i>e</i> in <i>b</i>,
  472 + * for each element <i>e</i> in <i>a</i> or <i>b</i>.
  473 + *
  474 + * @param a the first collection
  475 + * @param b the second collection
  476 + * @return <code>true</code> iff the collections contain the same elements with the same cardinalities.
  477 + */
  478 + public static boolean isEqualCollection(final Collection a, final Collection b) {
  479 + if (a == null || b == null) return false;
  480 + if (a.size() != b.size()) {
  481 + return false;
  482 + } else {
  483 + Map mapA = getCardinalityMap(a);
  484 + Map mapB = getCardinalityMap(b);
  485 + if (mapA.size() != mapB.size()) {
  486 + return false;
  487 + } else {
  488 + for (Object obj : mapA.keySet()) {
  489 + if (getFreq(obj, mapA) != getFreq(obj, mapB)) {
  490 + return false;
  491 + }
  492 + }
  493 + return true;
  494 + }
  495 + }
  496 + }
  497 +
  498 + /**
  499 + * 获取集合中元素的基数
  500 + * Returns the number of occurrences of <i>obj</i> in <i>coll</i>.
  501 + *
  502 + * @param obj the object to find the cardinality of
  503 + * @param coll the collection to search
  504 + * @return the the number of occurrences of obj in coll
  505 + */
  506 + public static <E> int cardinality(E obj, final Collection<E> coll) {
  507 + if (coll == null) return 0;
  508 + if (coll instanceof Set) {
  509 + return (coll.contains(obj) ? 1 : 0);
  510 + }
  511 + int count = 0;
  512 + if (obj == null) {
  513 + for (E e : coll) {
  514 + if (e == null) {
  515 + count++;
  516 + }
  517 + }
  518 + } else {
  519 + for (E e : coll) {
  520 + if (obj.equals(e)) {
  521 + count++;
  522 + }
  523 + }
  524 + }
  525 + return count;
  526 + }
  527 +
  528 + /**
  529 + * 查找第一个符合条件的元素
  530 + * Finds the first element in the given collection which matches the given predicate.
  531 + * <p>
  532 + * If the input collection or predicate is null, or no element of the collection
  533 + * matches the predicate, null is returned.
  534 + *
  535 + * @param collection the collection to search, may be null
  536 + * @param predicate the predicate to use, may be null
  537 + * @return the first element of the collection which matches the predicate or null if none could be found
  538 + */
  539 + public static <E> E find(Collection<E> collection, Predicate<E> predicate) {
  540 + if (collection == null || predicate == null) return null;
  541 + for (E item : collection) {
  542 + if (predicate.evaluate(item)) {
  543 + return item;
  544 + }
  545 + }
  546 + return null;
  547 + }
  548 +
  549 + /**
  550 + * 对所有元素做操作
  551 + * Executes the given closure on each element in the collection.
  552 + * <p>
  553 + * If the input collection or closure is null, there is no change made.
  554 + *
  555 + * @param collection the collection to get the input from, may be null
  556 + * @param closure the closure to perform, may be null
  557 + */
  558 + public static <E> void forAllDo(Collection<E> collection, Closure<E> closure) {
  559 + if (collection == null || closure == null) return;
  560 + int index = 0;
  561 + for (E e : collection) {
  562 + closure.execute(index++, e);
  563 + }
  564 + }
  565 +
  566 + /**
  567 + * 删除原集合中不符合条件的元素
  568 + * Filter the collection by applying a Predicate to each element. If the
  569 + * predicate returns false, remove the element.
  570 + * <p>
  571 + * If the input collection or predicate is null, there is no change made.
  572 + *
  573 + * @param collection the collection to get the input from, may be null
  574 + * @param predicate the predicate to use as a filter, may be null
  575 + */
  576 + public static <E> void filter(Collection<E> collection, Predicate<E> predicate) {
  577 + if (collection == null || predicate == null) return;
  578 + for (Iterator it = collection.iterator(); it.hasNext(); ) {
  579 + if (!predicate.evaluate((E) it.next())) {
  580 + it.remove();
  581 + }
  582 + }
  583 + }
  584 +
  585 + /**
  586 + * 查找出所有符合条件的元素并返回新集合
  587 + * Selects all elements from input collection which match the given predicate
  588 + * into an output collection.
  589 + * <p>
  590 + * A <code>null</code> predicate matches no elements.
  591 + *
  592 + * @param inputCollection the collection to get the input from, may not be null
  593 + * @param predicate the predicate to use, may be null
  594 + * @return the elements matching the predicate (new list)
  595 + * @throws NullPointerException if the input collection is null
  596 + */
  597 + public static <E> Collection<E> select(Collection<E> inputCollection, Predicate<E> predicate) {
  598 + if (inputCollection == null || predicate == null) return new ArrayList<>();
  599 + ArrayList<E> answer = new ArrayList<>(inputCollection.size());
  600 + for (E o : inputCollection) {
  601 + if (predicate.evaluate(o)) {
  602 + answer.add(o);
  603 + }
  604 + }
  605 + return answer;
  606 + }
  607 +
  608 + /**
  609 + * 查找出所有不符合条件的元素并返回新集合
  610 + * Selects all elements from inputCollection which don't match the given predicate
  611 + * into an output collection.
  612 + * <p>
  613 + * If the input predicate is <code>null</code>, the result is an empty list.
  614 + *
  615 + * @param inputCollection the collection to get the input from, may not be null
  616 + * @param predicate the predicate to use, may be null
  617 + * @return the elements <b>not</b> matching the predicate (new list)
  618 + * @throws NullPointerException if the input collection is null
  619 + */
  620 + public static <E> Collection<E> selectRejected(Collection<E> inputCollection, Predicate<E> predicate) {
  621 + if (inputCollection == null || predicate == null) return new ArrayList<>();
  622 + ArrayList<E> answer = new ArrayList<>(inputCollection.size());
  623 + for (E o : inputCollection) {
  624 + if (!predicate.evaluate(o)) {
  625 + answer.add(o);
  626 + }
  627 + }
  628 + return answer;
  629 + }
  630 +
  631 + /**
  632 + * 对原集合进行转变
  633 + * Transform the collection by applying a Transformer to each element.
  634 + * <p>
  635 + * If the input collection or transformer is null, there is no change made.
  636 + * <p>
  637 + * This routine is best for Lists, for which set() is used to do the
  638 + * transformations "in place." For other Collections, clear() and addAll()
  639 + * are used to replace elements.
  640 + * <p>
  641 + * If the input collection controls its input, such as a Set, and the
  642 + * Transformer creates duplicates (or are otherwise invalid), the
  643 + * collection may reduce in size due to calling this method.
  644 + *
  645 + * @param collection the collection to get the input from, may be null
  646 + * @param transformer the transformer to perform, may be null
  647 + */
  648 + public static <E1, E2> void transform(Collection<E1> collection, Transformer<E1, E2> transformer) {
  649 + if (collection == null || transformer == null) return;
  650 + if (collection instanceof List) {
  651 + List list = (List) collection;
  652 + for (ListIterator it = list.listIterator(); it.hasNext(); ) {
  653 + it.set(transformer.transform((E1) it.next()));
  654 + }
  655 + } else {
  656 + Collection resultCollection = collect(collection, transformer);
  657 + collection.clear();
  658 + collection.addAll(resultCollection);
  659 + }
  660 + }
  661 +
  662 +
  663 + /**
  664 + * 转变为新的集合
  665 + * Returns a new Collection consisting of the elements of inputCollection transformed
  666 + * by the given transformer.
  667 + * <p>
  668 + * If the input transformer is null, the result is an empty list.
  669 + *
  670 + * @param inputCollection the collection to get the input from, may be null
  671 + * @param transformer the transformer to use, may be null
  672 + * @return the transformed result (new list)
  673 + */
  674 + public static <E1, E2> Collection<E2> collect(final Collection<E1> inputCollection,
  675 + final Transformer<E1, E2> transformer) {
  676 + List<E2> answer = new ArrayList<>();
  677 + if (inputCollection == null || transformer == null) return answer;
  678 + for (E1 e1 : inputCollection) {
  679 + answer.add(transformer.transform(e1));
  680 + }
  681 + return answer;
  682 + }
  683 +
  684 + /**
  685 + * 查找到匹配的元素个数
  686 + * Counts the number of elements in the input collection that match the predicate.
  687 + * <p>
  688 + * A <code>null</code> collection or predicate matches no elements.
  689 + *
  690 + * @param collection the collection to get the input from, may be null
  691 + * @param predicate the predicate to use, may be null
  692 + * @return the number of matches for the predicate in the collection
  693 + */
  694 + public static <E> int countMatches(Collection<E> collection, Predicate<E> predicate) {
  695 + if (collection == null || predicate == null) return 0;
  696 + int count = 0;
  697 + for (E o : collection) {
  698 + if (predicate.evaluate(o)) {
  699 + count++;
  700 + }
  701 + }
  702 + return count;
  703 + }
  704 +
  705 + /**
  706 + * 判断集合是否存在符合条件的元素
  707 + * Answers true if a predicate is true for at least one element of a collection.
  708 + * <p>
  709 + * A <code>null</code> collection or predicate returns false.
  710 + *
  711 + * @param collection the collection to get the input from, may be null
  712 + * @param predicate the predicate to use, may be null
  713 + * @return true if at least one element of the collection matches the predicate
  714 + */
  715 + public static <E> boolean exists(Collection<E> collection, Predicate<E> predicate) {
  716 + if (collection == null || predicate == null) return false;
  717 + for (E o : collection) {
  718 + if (predicate.evaluate(o)) {
  719 + return true;
  720 + }
  721 + }
  722 + return false;
  723 + }
  724 +
  725 + /**
  726 + * 新增元素如果不为空
  727 + * Adds an element to the collection unless the element is null.
  728 + *
  729 + * @param collection the collection to add to, may be null
  730 + * @param object the object to add, if null it will not be added
  731 + * @return true if the collection changed
  732 + */
  733 + public static <E> boolean addIgnoreNull(Collection<E> collection, E object) {
  734 + if (collection == null) return false;
  735 + return (object != null && collection.add(object));
  736 + }
  737 +
  738 + /**
  739 + * 新增多个元素
  740 + * Adds all elements in the iteration to the given collection.
  741 + *
  742 + * @param collection the collection to add to, may be null
  743 + * @param iterator the iterator of elements to add, may be null
  744 + */
  745 + public static <E> void addAll(Collection<E> collection, Iterator<E> iterator) {
  746 + if (collection == null || iterator == null) return;
  747 + while (iterator.hasNext()) {
  748 + collection.add(iterator.next());
  749 + }
  750 + }
  751 +
  752 + /**
  753 + * Adds all elements in the enumeration to the given collection.
  754 + *
  755 + * @param collection the collection to add to, may be null
  756 + * @param enumeration the enumeration of elements to add, may be null
  757 + */
  758 + public static <E> void addAll(Collection<E> collection, Enumeration<E> enumeration) {
  759 + if (collection == null || enumeration == null) return;
  760 + while (enumeration.hasMoreElements()) {
  761 + collection.add(enumeration.nextElement());
  762 + }
  763 + }
  764 +
  765 + /**
  766 + * Adds all elements in the array to the given collection.
  767 + *
  768 + * @param collection the collection to add to, may be null
  769 + * @param elements the array of elements to add, may be null
  770 + */
  771 + public static <E> void addAll(Collection<E> collection, E[] elements) {
  772 + if (collection == null || elements == null || elements.length == 0) return;
  773 + collection.addAll(Arrays.asList(elements));
  774 + }
  775 +
  776 + /**
  777 + * 获取集合元素
  778 + * Returns the <code>index</code>-th value in <code>object</code>, throwing
  779 + * <code>IndexOutOfBoundsException</code> if there is no such element or
  780 + * <code>IllegalArgumentException</code> if <code>object</code> is not an
  781 + * instance of one of the supported types.
  782 + * <p>
  783 + * The supported types, and associated semantics are:
  784 + * <ul>
  785 + * <li> Map -- the value returned is the <code>Map.Entry</code> in position
  786 + * <code>index</code> in the map's <code>entrySet</code> iterator,
  787 + * if there is such an entry.</li>
  788 + * <li> List -- this method is equivalent to the list's get method.</li>
  789 + * <li> Array -- the <code>index</code>-th array entry is returned,
  790 + * if there is such an entry; otherwise an <code>IndexOutOfBoundsException</code>
  791 + * is thrown.</li>
  792 + * <li> Collection -- the value returned is the <code>index</code>-th object
  793 + * returned by the collection's default iterator, if there is such an element.</li>
  794 + * <li> Iterator or Enumeration -- the value returned is the
  795 + * <code>index</code>-th object in the Iterator/Enumeration, if there
  796 + * is such an element. The Iterator/Enumeration is advanced to
  797 + * <code>index</code> (or to the end, if <code>index</code> exceeds the
  798 + * number of entries) as a side effect of this method.</li>
  799 + * </ul>
  800 + *
  801 + * @param object the object to get a value from
  802 + * @param index the index to get
  803 + * @return the object at the specified index
  804 + * @throws IndexOutOfBoundsException if the index is invalid
  805 + * @throws IllegalArgumentException if the object type is invalid
  806 + */
  807 + public static Object get(Object object, int index) {
  808 + if (object == null) return null;
  809 + if (index < 0) {
  810 + throw new IndexOutOfBoundsException("Index cannot be negative: " + index);
  811 + }
  812 + if (object instanceof Map) {
  813 + Map map = (Map) object;
  814 + Iterator iterator = map.entrySet().iterator();
  815 + return get(iterator, index);
  816 + } else if (object instanceof List) {
  817 + return ((List) object).get(index);
  818 + } else if (object instanceof Object[]) {
  819 + return ((Object[]) object)[index];
  820 + } else if (object instanceof Iterator) {
  821 + Iterator it = (Iterator) object;
  822 + while (it.hasNext()) {
  823 + index--;
  824 + if (index == -1) {
  825 + return it.next();
  826 + } else {
  827 + it.next();
  828 + }
  829 + }
  830 + throw new IndexOutOfBoundsException("Entry does not exist: " + index);
  831 + } else if (object instanceof Collection) {
  832 + Iterator iterator = ((Collection) object).iterator();
  833 + return get(iterator, index);
  834 + } else if (object instanceof Enumeration) {
  835 + Enumeration it = (Enumeration) object;
  836 + while (it.hasMoreElements()) {
  837 + index--;
  838 + if (index == -1) {
  839 + return it.nextElement();
  840 + } else {
  841 + it.nextElement();
  842 + }
  843 + }
  844 + throw new IndexOutOfBoundsException("Entry does not exist: " + index);
  845 + } else {
  846 + try {
  847 + return Array.get(object, index);
  848 + } catch (IllegalArgumentException ex) {
  849 + throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
  850 + }
  851 + }
  852 + }
  853 +
  854 + /**
  855 + * 获取集合个数
  856 + * Gets the size of the collection/iterator specified.
  857 + * <p>
  858 + * This method can handles objects as follows
  859 + * <ul>
  860 + * <li>Collection - the collection size
  861 + * <li>Map - the map size
  862 + * <li>Array - the array size
  863 + * <li>Iterator - the number of elements remaining in the iterator
  864 + * <li>Enumeration - the number of elements remaining in the enumeration
  865 + * </ul>
  866 + *
  867 + * @param object the object to get the size of
  868 + * @return the size of the specified collection
  869 + * @throws IllegalArgumentException thrown if object is not recognised or null
  870 + */
  871 + public static int size(Object object) {
  872 + if (object == null) return 0;
  873 + int total = 0;
  874 + if (object instanceof Map) {
  875 + total = ((Map) object).size();
  876 + } else if (object instanceof Collection) {
  877 + total = ((Collection) object).size();
  878 + } else if (object instanceof Object[]) {
  879 + total = ((Object[]) object).length;
  880 + } else if (object instanceof Iterator) {
  881 + Iterator it = (Iterator) object;
  882 + while (it.hasNext()) {
  883 + total++;
  884 + it.next();
  885 + }
  886 + } else if (object instanceof Enumeration) {
  887 + Enumeration it = (Enumeration) object;
  888 + while (it.hasMoreElements()) {
  889 + total++;
  890 + it.nextElement();
  891 + }
  892 + } else {
  893 + try {
  894 + total = Array.getLength(object);
  895 + } catch (IllegalArgumentException ex) {
  896 + throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
  897 + }
  898 + }
  899 + return total;
  900 + }
  901 +
  902 + /**
  903 + * 判断个数是否为零
  904 + * Checks if the specified collection/array/iterator is empty.
  905 + * <p>
  906 + * This method can handles objects as follows
  907 + * <ul>
  908 + * <li>Collection - via collection isEmpty
  909 + * <li>Map - via map isEmpty
  910 + * <li>Array - using array size
  911 + * <li>Iterator - via hasNext
  912 + * <li>Enumeration - via hasMoreElements
  913 + * </ul>
  914 + * <p>
  915 + * Note: This method is named to avoid clashing with
  916 + * {@link #isEmpty(Collection)}.
  917 + *
  918 + * @param object the object to get the size of, not null
  919 + * @return true if empty
  920 + * @throws IllegalArgumentException thrown if object is not recognised or null
  921 + */
  922 + public static boolean sizeIsEmpty(Object object) {
  923 + if (object == null) return true;
  924 + if (object instanceof Collection) {
  925 + return ((Collection) object).isEmpty();
  926 + } else if (object instanceof Map) {
  927 + return ((Map) object).isEmpty();
  928 + } else if (object instanceof Object[]) {
  929 + return ((Object[]) object).length == 0;
  930 + } else if (object instanceof Iterator) {
  931 + return !((Iterator) object).hasNext();
  932 + } else if (object instanceof Enumeration) {
  933 + return !((Enumeration) object).hasMoreElements();
  934 + } else {
  935 + try {
  936 + return Array.getLength(object) == 0;
  937 + } catch (IllegalArgumentException ex) {
  938 + throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
  939 + }
  940 + }
  941 + }
  942 +
  943 + /**
  944 + * 判断是否为空
  945 + * Null-safe check if the specified collection is empty.
  946 + * <p>
  947 + * Null returns true.
  948 + *
  949 + * @param coll the collection to check, may be null
  950 + * @return true if empty or null
  951 + */
  952 + public static boolean isEmpty(Collection coll) {
  953 + return coll == null || coll.size() == 0;
  954 + }
  955 +
  956 + /**
  957 + * 判断是否非空
  958 + * Null-safe check if the specified collection is not empty.
  959 + * <p>
  960 + * Null returns false.
  961 + *
  962 + * @param coll the collection to check, may be null
  963 + * @return true if non-null and non-empty
  964 + */
  965 + public static boolean isNotEmpty(Collection coll) {
  966 + return !isEmpty(coll);
  967 + }
  968 +
  969 +
  970 + /**
  971 + * 保留元素
  972 + * Returns a collection containing all the elements in <code>collection</code>
  973 + * that are also in <code>retain</code>. The cardinality of an element <code>e</code>
  974 + * in the returned collection is the same as the cardinality of <code>e</code>
  975 + * in <code>collection</code> unless <code>retain</code> does not contain <code>e</code>, in which
  976 + * case the cardinality is zero. This method is useful if you do not wish to modify
  977 + * the collection <code>c</code> and thus cannot call <code>c.retainAll(retain);</code>.
  978 + *
  979 + * @param collection the collection whose contents are the target of the #retailAll operation
  980 + * @param retain the collection containing the elements to be retained in the returned collection
  981 + * @return a <code>Collection</code> containing all the elements of <code>collection</code>
  982 + * that occur at least once in <code>retain</code>.
  983 + */
  984 + public static <E> Collection<E> retainAll(Collection<E> collection, Collection<E> retain) {
  985 + if (collection == null || retain == null) return new ArrayList<>();
  986 + List<E> list = new ArrayList<>();
  987 + for (E item : collection) {
  988 + if (retain.contains(item)) {
  989 + list.add(item);
  990 + }
  991 + }
  992 + return list;
  993 + }
  994 +
  995 + /**
  996 + * 删除下来
  997 + * Removes the elements in <code>remove</code> from <code>collection</code>. That is, this
  998 + * method returns a collection containing all the elements in <code>c</code>
  999 + * that are not in <code>remove</code>. The cardinality of an element <code>e</code>
  1000 + * in the returned collection is the same as the cardinality of <code>e</code>
  1001 + * in <code>collection</code> unless <code>remove</code> contains <code>e</code>, in which
  1002 + * case the cardinality is zero. This method is useful if you do not wish to modify
  1003 + * the collection <code>c</code> and thus cannot call <code>collection.removeAll(remove);</code>.
  1004 + *
  1005 + * @param collection the collection from which items are removed (in the returned collection)
  1006 + * @param remove the items to be removed from the returned <code>collection</code>
  1007 + * @return a <code>Collection</code> containing all the elements of <code>collection</code> except
  1008 + * any elements that also occur in <code>remove</code>.
  1009 + */
  1010 + public static <E> Collection<E> removeAll(Collection<E> collection, Collection<E> remove) {
  1011 + if (collection == null) return new ArrayList<>();
  1012 + if (remove == null) return new ArrayList<>(collection);
  1013 + List<E> list = new ArrayList<>();
  1014 + for (E obj : collection) {
  1015 + if (!remove.contains(obj)) {
  1016 + list.add(obj);
  1017 + }
  1018 + }
  1019 + return list;
  1020 + }
  1021 +
  1022 + /**
  1023 + * Randomly permutes the specified list using a default source of randomness.
  1024 + *
  1025 + * @param list the list to be shuffled.
  1026 + * @throws UnsupportedOperationException if the specified list or
  1027 + * its list-iterator does not support the <tt>set</tt> operation.
  1028 + */
  1029 + public static <T> void shuffle(List<T> list) {
  1030 + Collections.shuffle(list);
  1031 + }
  1032 +
  1033 + /**
  1034 + * 集合转为字符串
  1035 + * Return the string of collection.
  1036 + *
  1037 + * @param collection The collection.
  1038 + * @return the string of collection
  1039 + */
  1040 + public static String toString(Collection collection) {
  1041 + if (collection == null) return "null";
  1042 + return collection.toString();
  1043 + }
  1044 +
  1045 + public interface Closure<E> {
  1046 + void execute(int index, E item);
  1047 + }
  1048 +
  1049 + public interface Transformer<E1, E2> {
  1050 + E2 transform(E1 input);
  1051 + }
  1052 +
  1053 + public interface Predicate<E> {
  1054 + boolean evaluate(E item);
  1055 + }
  1056 +}
core/base/src/main/java/com/cnlive/core/libs/base/util/ColorUtils.java 0 → 100644
  1 +package com.cnlive.core.libs.base.util;
  2 +
  3 +import android.content.Context;
  4 +import android.graphics.Color;
  5 +
  6 +import androidx.annotation.ColorInt;
  7 +import androidx.annotation.ColorRes;
  8 +import androidx.annotation.FloatRange;
  9 +import androidx.annotation.IntRange;
  10 +import androidx.annotation.NonNull;
  11 +import androidx.core.content.ContextCompat;
  12 +
  13 +/**
  14 + * <pre>
  15 + * author: Blankj
  16 + * blog : http://blankj.com
  17 + * time : 2019/01/15
  18 + * desc : utils about color
  19 + * </pre>
  20 + * getColor : 获取颜色
  21 + * setAlphaComponent: 设置颜色透明度值
  22 + * setRedComponent : 设置颜色红色值
  23 + * setGreenComponent: 设置颜色绿色值
  24 + * setBlueComponent : 设置颜色蓝色值
  25 + * string2Int : 颜色串转颜色值
  26 + * int2RgbString : 颜色值转 RGB 串
  27 + * int2ArgbString : 颜色值转 ARGB 串
  28 + * getRandomColor : 获取随机色
  29 + */
  30 +public final class ColorUtils {
  31 +
  32 + private ColorUtils() {
  33 + throw new UnsupportedOperationException("u can't instantiate me...");
  34 + }
  35 +
  36 + /**
  37 + * 获取颜色
  38 + * Returns a color associated with a particular resource ID.
  39 + *
  40 + * @param id The desired resource identifier.
  41 + * @return a color associated with a particular resource ID
  42 + */
  43 + public static int getColor(Context context, @ColorRes int id) {
  44 + return ContextCompat.getColor(context, id);
  45 + }
  46 +
  47 + /**
  48 + * 设置颜色透明度值
  49 + * Set the alpha component of {@code color} to be {@code alpha}.
  50 + *
  51 + * @param color The color.
  52 + * @param alpha Alpha component \([0..255]\) of the color.
  53 + * @return the {@code color} with {@code alpha} component
  54 + */
  55 + public static int setAlphaComponent(@ColorInt final int color,
  56 + @IntRange(from = 0x0, to = 0xFF) int alpha) {
  57 + return (color & 0x00ffffff) | (alpha << 24);
  58 + }
  59 +
  60 + /**
  61 + * Set the alpha component of {@code color} to be {@code alpha}.
  62 + *
  63 + * @param color The color.
  64 + * @param alpha Alpha component \([0..1]\) of the color.
  65 + * @return the {@code color} with {@code alpha} component
  66 + */
  67 + public static int setAlphaComponent(@ColorInt int color,
  68 + @FloatRange(from = 0, to = 1) float alpha) {
  69 + return (color & 0x00ffffff) | ((int) (alpha * 255.0f + 0.5f) << 24);
  70 + }
  71 +
  72 + /**
  73 + * 设置颜色红色值
  74 + * Set the red component of {@code color} to be {@code red}.
  75 + *
  76 + * @param color The color.
  77 + * @param red Red component \([0..255]\) of the color.
  78 + * @return the {@code color} with {@code red} component
  79 + */
  80 + public static int setRedComponent(@ColorInt int color,
  81 + @IntRange(from = 0x0, to = 0xFF) int red) {
  82 + return (color & 0xff00ffff) | (red << 16);
  83 + }
  84 +
  85 + /**
  86 + * Set the red component of {@code color} to be {@code red}.
  87 + *
  88 + * @param color The color.
  89 + * @param red Red component \([0..1]\) of the color.
  90 + * @return the {@code color} with {@code red} component
  91 + */
  92 + public static int setRedComponent(@ColorInt int color,
  93 + @FloatRange(from = 0, to = 1) float red) {
  94 + return (color & 0xff00ffff) | ((int) (red * 255.0f + 0.5f) << 16);
  95 + }
  96 +
  97 + /**
  98 + * 设置颜色绿色值
  99 + * Set the green component of {@code color} to be {@code green}.
  100 + *
  101 + * @param color The color.
  102 + * @param green Green component \([0..255]\) of the color.
  103 + * @return the {@code color} with {@code green} component
  104 + */
  105 + public static int setGreenComponent(@ColorInt int color,
  106 + @IntRange(from = 0x0, to = 0xFF) int green) {
  107 + return (color & 0xffff00ff) | (green << 8);
  108 + }
  109 +
  110 + /**
  111 + * Set the green component of {@code color} to be {@code green}.
  112 + *
  113 + * @param color The color.
  114 + * @param green Green component \([0..1]\) of the color.
  115 + * @return the {@code color} with {@code green} component
  116 + */
  117 + public static int setGreenComponent(@ColorInt int color,
  118 + @FloatRange(from = 0, to = 1) float green) {
  119 + return (color & 0xffff00ff) | ((int) (green * 255.0f + 0.5f) << 8);
  120 + }
  121 +
  122 + /**
  123 + * 设置颜色蓝色值
  124 + * Set the blue component of {@code color} to be {@code blue}.
  125 + *
  126 + * @param color The color.
  127 + * @param blue Blue component \([0..255]\) of the color.
  128 + * @return the {@code color} with {@code blue} component
  129 + */
  130 + public static int setBlueComponent(@ColorInt int color,
  131 + @IntRange(from = 0x0, to = 0xFF) int blue) {
  132 + return (color & 0xffffff00) | blue;
  133 + }
  134 +
  135 + /**
  136 + * Set the blue component of {@code color} to be {@code blue}.
  137 + *
  138 + * @param color The color.
  139 + * @param blue Blue component \([0..1]\) of the color.
  140 + * @return the {@code color} with {@code blue} component
  141 + */
  142 + public static int setBlueComponent(@ColorInt int color,
  143 + @FloatRange(from = 0, to = 1) float blue) {
  144 + return (color & 0xffffff00) | (int) (blue * 255.0f + 0.5f);
  145 + }
  146 +
  147 + /**
  148 + * 颜色串转颜色值
  149 + * Color-string to color-int.
  150 + * <p>Supported formats are:</p>
  151 + *
  152 + * <ul>
  153 + * <li><code>#RRGGBB</code></li>
  154 + * <li><code>#AARRGGBB</code></li>
  155 + * </ul>
  156 + *
  157 + * <p>The following names are also accepted: <code>red</code>, <code>blue</code>,
  158 + * <code>green</code>, <code>black</code>, <code>white</code>, <code>gray</code>,
  159 + * <code>cyan</code>, <code>magenta</code>, <code>yellow</code>, <code>lightgray</code>,
  160 + * <code>darkgray</code>, <code>grey</code>, <code>lightgrey</code>, <code>darkgrey</code>,
  161 + * <code>aqua</code>, <code>fuchsia</code>, <code>lime</code>, <code>maroon</code>,
  162 + * <code>navy</code>, <code>olive</code>, <code>purple</code>, <code>silver</code>,
  163 + * and <code>teal</code>.</p>
  164 + *
  165 + * @param colorString The color-string.
  166 + * @return color-int
  167 + * @throws IllegalArgumentException The string cannot be parsed.
  168 + */
  169 + public static int string2Int(@NonNull String colorString) {
  170 + return Color.parseColor(colorString);
  171 + }
  172 +
  173 + /**
  174 + * 颜色值转 RGB 串
  175 + * Color-int to color-string.
  176 + *
  177 + * @param colorInt The color-int.
  178 + * @return color-string
  179 + */
  180 + public static String int2RgbString(@ColorInt int colorInt) {
  181 + colorInt = colorInt & 0x00ffffff;
  182 + String color = Integer.toHexString(colorInt);
  183 + while (color.length() < 6) {
  184 + color = "0" + color;
  185 + }
  186 + return "#" + color;
  187 + }
  188 +
  189 + /**
  190 + * 颜色值转 ARGB 串
  191 + * Color-int to color-string.
  192 + *
  193 + * @param colorInt The color-int.
  194 + * @return color-string
  195 + */
  196 + public static String int2ArgbString(@ColorInt final int colorInt) {
  197 + String color = Integer.toHexString(colorInt);
  198 + while (color.length() < 6) {
  199 + color = "0" + color;
  200 + }
  201 + while (color.length() < 8) {
  202 + color = "f" + color;
  203 + }
  204 + return "#" + color;
  205 + }
  206 +
  207 + /**
  208 + * 获取随机色
  209 + * Return the random color.
  210 + *
  211 + * @return the random color
  212 + */
  213 + public static int getRandomColor() {
  214 + return getRandomColor(true);
  215 + }
  216 +
  217 + /**
  218 + * Return the random color.
  219 + *
  220 + * @param supportAlpha True to support alpha, false otherwise.
  221 + * @return the random color
  222 + */
  223 + public static int getRandomColor(final boolean supportAlpha) {
  224 + int high = supportAlpha ? (int) (Math.random() * 0x100) << 24 : 0xFF000000;
  225 + return high | (int) (Math.random() * 0x1000000);
  226 + }
  227 +}
core/base/src/main/java/com/cnlive/core/libs/base/util/EncodeUtils.java 0 → 100644
  1 +package com.cnlive.core.libs.base.util;
  2 +
  3 +import android.os.Build;
  4 +import android.text.Html;
  5 +import android.util.Base64;
  6 +
  7 +import java.io.UnsupportedEncodingException;
  8 +import java.net.URLDecoder;
  9 +import java.net.URLEncoder;
  10 +
  11 +/**
  12 + * <pre>
  13 + * author: Blankj
  14 + * blog : http://blankj.com
  15 + * time : 2016/08/07
  16 + * desc : utils about encode
  17 + * </pre>
  18 + */
  19 +public final class EncodeUtils {
  20 +
  21 + private EncodeUtils() {
  22 + throw new UnsupportedOperationException("u can't instantiate me...");
  23 + }
  24 +
  25 + /**
  26 + * URL 编码
  27 + * Return the urlencoded string.
  28 + *
  29 + * @param input The input.
  30 + * @return the urlencoded string
  31 + */
  32 + public static String urlEncode(final String input) {
  33 + return urlEncode(input, "UTF-8");
  34 + }
  35 +
  36 + /**
  37 + * URL 解码
  38 + * Return the urlencoded string.
  39 + *
  40 + * @param input The input.
  41 + * @param charsetName The name of charset.
  42 + * @return the urlencoded string
  43 + */
  44 + public static String urlEncode(final String input, final String charsetName) {
  45 + if (input == null || input.length() == 0) return "";
  46 + try {
  47 + return URLEncoder.encode(input, charsetName);
  48 + } catch (UnsupportedEncodingException e) {
  49 + throw new AssertionError(e);
  50 + }
  51 + }
  52 +
  53 + /**
  54 + * Return the string of decode urlencoded string.
  55 + *
  56 + * @param input The input.
  57 + * @return the string of decode urlencoded string
  58 + */
  59 + public static String urlDecode(final String input) {
  60 + return urlDecode(input, "UTF-8");
  61 + }
  62 +
  63 + /**
  64 + * Return the string of decode urlencoded string.
  65 + *
  66 + * @param input The input.
  67 + * @param charsetName The name of charset.
  68 + * @return the string of decode urlencoded string
  69 + */
  70 + public static String urlDecode(final String input, final String charsetName) {
  71 + if (input == null || input.length() == 0) return "";
  72 + try {
  73 + return URLDecoder.decode(input, charsetName);
  74 + } catch (UnsupportedEncodingException e) {
  75 + throw new AssertionError(e);
  76 + }
  77 + }
  78 +
  79 + /**
  80 + * Base64 编码
  81 + * Return Base64-encode bytes.
  82 + *
  83 + * @param input The input.
  84 + * @return Base64-encode bytes
  85 + */
  86 + public static byte[] base64Encode(final String input) {
  87 + return base64Encode(input.getBytes());
  88 + }
  89 +
  90 + /**
  91 + * Return Base64-encode bytes.
  92 + *
  93 + * @param input The input.
  94 + * @return Base64-encode bytes
  95 + */
  96 + public static byte[] base64Encode(final byte[] input) {
  97 + if (input == null || input.length == 0) return new byte[0];
  98 + return Base64.encode(input, Base64.NO_WRAP);
  99 + }
  100 +
  101 + /**
  102 + * Return Base64-encode string.
  103 + *
  104 + * @param input The input.
  105 + * @return Base64-encode string
  106 + */
  107 + public static String base64Encode2String(final byte[] input) {
  108 + if (input == null || input.length == 0) return "";
  109 + return Base64.encodeToString(input, Base64.NO_WRAP);
  110 + }
  111 +
  112 + /**
  113 + * Base64 解码
  114 + * Return the bytes of decode Base64-encode string.
  115 + *
  116 + * @param input The input.
  117 + * @return the string of decode Base64-encode string
  118 + */
  119 + public static byte[] base64Decode(final String input) {
  120 + if (input == null || input.length() == 0) return new byte[0];
  121 + return Base64.decode(input, Base64.NO_WRAP);
  122 + }
  123 +
  124 + /**
  125 + * Return the bytes of decode Base64-encode bytes.
  126 + *
  127 + * @param input The input.
  128 + * @return the bytes of decode Base64-encode bytes
  129 + */
  130 + public static byte[] base64Decode(final byte[] input) {
  131 + if (input == null || input.length == 0) return new byte[0];
  132 + return Base64.decode(input, Base64.NO_WRAP);
  133 + }
  134 +
  135 + /**
  136 + * Html 编码
  137 + * Return html-encode string.
  138 + *
  139 + * @param input The input.
  140 + * @return html-encode string
  141 + */
  142 + public static String htmlEncode(final CharSequence input) {
  143 + if (input == null || input.length() == 0) return "";
  144 + StringBuilder sb = new StringBuilder();
  145 + char c;
  146 + for (int i = 0, len = input.length(); i < len; i++) {
  147 + c = input.charAt(i);
  148 + switch (c) {
  149 + case '<':
  150 + sb.append("&lt;"); //$NON-NLS-1$
  151 + break;
  152 + case '>':
  153 + sb.append("&gt;"); //$NON-NLS-1$
  154 + break;
  155 + case '&':
  156 + sb.append("&amp;"); //$NON-NLS-1$
  157 + break;
  158 + case '\'':
  159 + //http://www.w3.org/TR/xhtml1
  160 + // The named character reference &apos; (the apostrophe, U+0027) was
  161 + // introduced in XML 1.0 but does not appear in HTML. Authors should
  162 + // therefore use &#39; instead of &apos; to work as expected in HTML 4
  163 + // user agents.
  164 + sb.append("&#39;"); //$NON-NLS-1$
  165 + break;
  166 + case '"':
  167 + sb.append("&quot;"); //$NON-NLS-1$
  168 + break;
  169 + default:
  170 + sb.append(c);
  171 + }
  172 + }
  173 + return sb.toString();
  174 + }
  175 +
  176 + /**
  177 + * Html 解码
  178 + * Return the string of decode html-encode string.
  179 + *
  180 + * @param input The input.
  181 + * @return the string of decode html-encode string
  182 + */
  183 + @SuppressWarnings("deprecation")
  184 + public static CharSequence htmlDecode(final String input) {
  185 + if (input == null || input.length() == 0) return "";
  186 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
  187 + return Html.fromHtml(input, Html.FROM_HTML_MODE_LEGACY);
  188 + } else {
  189 + return Html.fromHtml(input);
  190 + }
  191 + }
  192 +
  193 + /**
  194 + * Return the binary encoded string padded with one space
  195 + *
  196 + * @param input
  197 + * @return binary string
  198 + */
  199 + public static String binEncode(final String input) {
  200 + StringBuilder stringBuilder = new StringBuilder();
  201 + for (char i : input.toCharArray()) {
  202 + stringBuilder.append(Integer.toBinaryString(i));
  203 + stringBuilder.append(' ');
  204 + }
  205 + return stringBuilder.toString();
  206 + }
  207 +
  208 + /**
  209 + * 编码解码相关
  210 + * Return UTF-8 String from binary
  211 + *
  212 + * @param input binary string
  213 + * @return UTF-8 String
  214 + * urlEncode : URL 编码
  215 + * urlDecode : URL 解码
  216 + * base64Encode : Base64 编码
  217 + * base64Encode2String: Base64 编码
  218 + * base64Decode : Base64 解码
  219 + * htmlEncode : Html 编码
  220 + * htmlDecode : Html 解码
  221 + */
  222 + public static String binDecode(final String input) {
  223 + String[] splitted = input.split(" ");
  224 + StringBuilder sb = new StringBuilder();
  225 + for (String i : splitted) {
  226 + sb.append(((char) Integer.parseInt(i.replace(" ", ""), 2)));
  227 + }
  228 + return sb.toString();
  229 + }
  230 +}