下邊是整理的一些Java開發的utils,順便吐槽下新浪博客的編輯器排版跟我寫的博客一樣 爛,所以改用博客園
一、字符串
1. Java中String與其他類型之間的轉換
-
String與日期對象
1 public static SimpleDateFormat df1 = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss", Locale.US); 2 public static SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US); 3 df2.format(df1.parse(time_local));
-
String與八種基本類型(以int為例)
1 try { 2 int i = Integer.parseInt(str); 3 } catch (NumberFormatException e) { //str中可能有非數字 4 e.printStackTrace(); 5 }
2. 去掉字符串前面的0
- 使用replaceAll(正則或者目標字符串,要替換上的字符串)
1 String str = "000000001234034120"; 2 String newStr = str.replaceAll("^(0+)", ""); 3 System.out.println(newStr);
這里說明下replace和replaceAll的區別:replace的參數是char和CharSequence,即可以支持字符的替換,也支持字符串的替換;replaceAll的參數是regex,即基於正則表達式的替換。
- 使用replaceFirst(正則或者目標字符串,要替換上的字符串)
1 String str = "000000001234034120"; 2 String newStr = str.replaceFirst("^(0+)", ""); 3 System.out.println(newStr);
3. String.format方法
1 String formatted = String.format("%s今年%d歲。", "我", 25); // 打印結果:"我今年25歲。"
3. String == 和equals方法
-
“==”判斷的是地址值,equals()方法判斷的是內容
1 str1.equals(str2) 2 str1.hashCode()==str2.hashCode()
-
hashCode是一樣的,hashCode相同可能是同一個對象,也可能是不同的對象,但是hashCode不同就肯定是不同的對象。
如果兩個對象equals相等,那么這兩個對象的HashCode一定也相同
如果兩個對象的HashCode相同,不代表兩個對象就相同,只能說明這兩個對象在散列存儲結構中,存放於同一個位置 - equals和equalsIgnoreCase方法對比
equals方法來自於Object類,默認比較兩個對象的內存地址,equals在把對象放入HashMap中會被掉用;
equalsIgnoreCase是String特有的方法,比較的是兩個String對象是否相等(並且忽略大小寫)
4. StringUtils的join方法
-
包路徑:org.apache.commons.lang3.StringUtils;
- 用法:將數組元素用特殊連接符連接
StringUtils.join(array, "-")
- 源碼:

/** * <p>Joins the elements of the provided array into a single String * containing the provided list of elements.</p> * * <p>No delimiter is added before or after the list. * Null objects or empty strings within the array are represented by * empty strings.</p> * * <pre> * StringUtils.join(null, *) = null * StringUtils.join([], *) = "" * StringUtils.join([null], *) = "" * StringUtils.join(["a", "b", "c"], ';') = "a;b;c" * StringUtils.join(["a", "b", "c"], null) = "abc" * StringUtils.join([null, "", "a"], ';') = ";;a" * </pre> * * @param array the array of values to join together, may be null * @param separator the separator character to use * @return the joined String, {@code null} if null array input * @since 2.0 */ public static String join(final Object[] array, final char separator) { if (array == null) { return null; } return join(array, separator, 0, array.length); }
5. URLEncode編碼 與 URLDecode解碼
String mytext = java.net.URLEncoder.encode("中國", "utf-8");
String mytext2 = java.net.URLDecoder.decode(mytext, "utf-8");
這兩條語句在同一個頁面中的話,得到的結果是:
mytext: %E4%B8%AD%E5%9B%BD
mytex2: 中國
5. 字符編碼和字符串所占字節數
二、Spring
1. JSONField 注解
-
指定字段的名稱
1 @JSONField(name="role_name") 2 private String roleName;
-
使用format制定日期格式
public class A { // 配置date序列化和反序列使用yyyyMMdd日期格式 @JSONField(format="yyyyMMdd") public Date date; }
-
指定字段的順序
1 public static class VO { 2 @JSONField(ordinal = 3) 3 private int f0; 4 5 @JSONField(ordinal = 2) 6 private int f1; 7 8 @JSONField(ordinal = 1) 9 private int f2;
-
使用serialize/deserialize指定字段不序列化
1 public class A { 2 @JSONField(serialize=false) 3 public Date date; 4 }
三、隨機數
- 使用Random類
Random類可以產生 boolean、int、long、float, byte 數組以及 double 類型的隨機數,這是它與 random()方法最大的不同之處,random()方法只能產生double類型的 0~1的隨機數。
Random 類位於 java.util 包中,該類常用的有如下兩個構造方法。
Random():該構造方法使用一個和當前系統時間對應的數字作為種子數,然后使用這個種子數構造 Random 對象。
Random(long seed):使用單個 long 類型的參數創建一個新的隨機數生成器。例如:
1 public static void main(String[] args) 2 { 3 Random r=new Random(); 4 double d1=r.nextDouble(); //生成[0,1.0]區間的小數 5 double d2=r.nextDouble()*7; //生成[0,7.0]區間的小數 6 int i1=r.nextInt(10); //生成[0,10]區間的整數 7 int i2=r.nextInt(18)-3; //生成[-3,15]區間的整數 8 long l1=r.nextLong(); //生成一個隨機長整型值 9 boolean b1=r.nextBoolean(); //生成一個隨機布爾型值True或者False 10 float f1=r.nextFloat{); //生成一個隨機浮點型值 11 }
- Math類的random()方法
該方法沒有參數,它默認會返回大於等於0.0、小於1.0的double類型隨機數。如下:
1 public static void main(String[] args) 2 { 3 int min=0; //定義隨機數的最小值 4 int max=100; //定義隨機數的最大值 5 //產生一個1~100的數 6 int s=(int)min+(int)(Math.random()*(max-min)); 7 }
- 當前日期和時間
- 時鍾序列
- 全局唯一的IEEE機器識別號,如果有網卡,從網卡MAC地址獲得,沒有網卡以其他方式獲得。
1 //獲得指定數目的UUID 2 public static String[] getUUID(int number){ 3 if(number < 1){ 4 return null; 5 } 6 String[] retArray = new String[number]; 7 for(int i=0;i){ 8 retArray[i] = getUUID(); 9 } 10 return retArray; 11 } 12 //獲得一個UUID 13 public static String getUUID(){ 14 String uuid = UUID.randomUUID().toString(); 15 //去掉“-”符號 16 return uuid.replaceAll("-", ""); 17 }
四、文件
1. FileUtils
具有封裝的讀寫文件、復制文件等功能。例如:
1 import org.apache.commons.io.FileUtils; 2 List lines = new ArrayList(); 3 ... 4 FileUtils.writeLines(new File("/Users/admin/1.txt"), lines, true); 5 String result = FileUtils.readFileToString(new File("/Users/admin/1.txt"), "UTF-8");
2. 配置文件讀取
一般情況下,我們用到的資源文件(各種xml,properites,xsd文件等)都放在src/main/resources下面,利用maven打包時,maven能把這些資源文件打包到相應的jar或者war里。在程序中就可以直接讀取了,例如:
-
properties文件
1 InputStream input =Thread.currentThread().getContextClassLoader().getResourceAsStream("abc.properties"); 2 Properties prop = new Properties(); 3 prop.load(input);
-
yaml文件
1 InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(yamlPath); 2 Yaml yaml = new Yaml(); 3 HashMap map = yaml.loadAs(inputStream, HashMap.class);
五、Java反射
1. 反射取私有方法
- 在調用私有方法時必須用getDeclaredMethod,getDeclaredMethod和getMethod區別如下:
getMethod:Returns a object that reflects the specified public member method of the class or interface represented by this object.(只能獲取public的方法)
getDeclaredMethod:Returns a object that reflects the specified declared method of the class or interface represented by this object. (能獲取類中所有方法)
- 調用私有方法時除了在調用之前需要設置setAccessible(true)
2. Java Agent(JDK 1.5及以上)
3. Java Assist
六、網絡
1. 主機名轉IP
1 String ip = InetAddress.getByName(hostName).getHostAddress();
2. HttpClient
HttpClient httpclient = new DefaultHttpClient(); httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, Config.20000);//連接時間20s httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 60000);//數據傳輸時間60s
不設置的話如果服務器無響應,可能返回(404 50x),如果沒有返回則java線程會一直等待。
七、緩存
1. Guava Cache
注:通過RemovalNotification.getCause()可以知道該對象被移除的原因1 public enum RemovalCause { 2 //用戶手動移除 3 EXPLICIT, 4 //用戶手動替換 5 REPLACED, 6 //被垃圾回收 7 COLLECTED, 8 //超時過期 9 EXPIRED, 10 //由於緩存大小限制 11 SIZE; 12 }
八、日期
1. TimeUnit
TimeUnit提供了各種時間方法,比如常用的toMillis、toNaNos、sleep(Long timeout)等等,可讀性極高,使用方便且性能也不錯,具體使用方法參考:Java-TimeUnit類常用方法詳解,對比一下:
1 // TimeUnit 2 TimeUnit.MILLISECONDS.sleep(10); 3 TimeUnit.SECONDS.sleep(10); 4 TimeUnit.MINUTES.sleep(10); 5 6 // 原生Thread方法 7 Thread.sleep(10); 8 Thread.sleep(10*1000); 9 Thread.sleep(10*60*1000);
2. Java8只取年月日的java.util.Date(時分秒清零)對象
1 // set current date 2 date = new Date(); 3 Calendar cal1 = Calendar.getInstance(); 4 cal1.setTime(date); 5 // clear minute second milliSecond 6 cal1.set(Calendar.MINUTE, 0); 7 cal1.set(Calendar.SECOND, 0); 8 cal1.set(Calendar.MILLISECOND, 0); 9 date = cal1.getTime();
3. java.util.Date轉java.sql.Date
1 Date utilDate = new Date();//uilt.Date 2 System.out.println("utilDate : " + utilDate); 3 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 4 System.out.println("format : " + format.format(utilDate)); 5 6 System.out.println("**********************************************"); 7 8 Timestamp sqlDate = new Timestamp(utilDate.getTime());//uilt.Date轉sql.Date 9 System.out.println("sqlDate : " + sqlDate); 10 System.out.println("format : " + format.format(sqlDate));
九、代碼規范
1. HashMap初始容量設置
-
根據阿里巴巴Java開發手冊上建議HashMap初始化時設置已知的大小,如果不超過16個,那么設置成默認大小16:
集合初始化時, 指定集合初始值大小。
說明: HashMap使用HashMap(int initialCapacity)初始化,
正例:initialCapacity = (需要存儲的元素個數 / 負載因子) + 1。注意負載因子(即loader factor)默認為0.75, 如果暫時無法確定初始值大小,請設置為16(即默認值)。
反例:HashMap需要放置1024個元素,由於沒有設置容量初始大小,隨着元素不斷增加,容量7次被迫擴大,resize需要重建hash表,嚴重影響性能
2. 減少if/else書寫(一般嵌套不超過三層為好)
- 提前return
1 if (condition) { 2 // do something 3 } else { 4 return xxx; 5 }
這種情況條件取反,干掉else
1 if (!condition) { 2 return xxx; 3 } 4 5 // do something
- 策略模式
有種情況是根據不同的參數走不同的邏輯,先看一般寫法:
1 if (strategy.equals("fast")) { 2 // 快速執行 3 } else if ("strategy.equals("normal")) { 4 // 正常執行 5 } else if ("strategy.equals("smooth")) { 6 // 平滑執行 7 } else if ("strategy.equals("slow")) { 8 // 慢慢執行 9 }
其實可以用枚舉
1 public enum Stategy { 2 FAST{ 3 @Override 4 public void run() { 5 System.out.println("fast---"); 6 } 7 }, 8 NORMAL{ 9 @Override 10 public void run() { 11 System.out.println("normal---"); 12 } 13 }, 14 SMOOTH{ 15 @Override 16 public void run() { 17 System.out.println("smooth---"); 18 } 19 }, 20 SLOW { 21 @Override 22 public void run() { 23 System.out.println("slow---"); 24 } 25 }; 26 27 public abstract void run(); 28 }
最后,可以通過param執行不同邏輯
1 Strategy strategy = Strategy.valueOf(param); 2 Strategy.run();
- 用Optional
1 if (user == null) { 2 // do action 1 3 } else { 4 // do action2 5 }
可以改為
1 Optional<User> userOptional = Optional.ofNullable(user); 2 userOptional.map(action1).orElse(action2);
十、thrift
1. thrift文件的使用
最近看別人的老項目用到了thrift文件,以前沒用過,挺好玩的,記錄一下。剛開始從gitlab上clone下來以后,會發現有些包會爆紅:
同時src目錄下有thrift文件
問了下同事說是要compile一下,還得先安裝0.9.3的thrift(還有一些插件,一定要翻牆,如果沒有全局設置的話,需要在shell里邊重新設置下)
1 export http_proxy=http://127.0.0.1:1087; export https_proxy=http://127.0.0.1:1087
工程里修改pom文件
1 <build> 2 <plugins> 3 <plugin> 4 <artifactId>maven-assembly-plugin</artifactId> 5 <configuration> 6 <descriptorRefs> 7 <descriptorRef>jar-with-dependencies</descriptorRef> 8 </descriptorRefs> 9 </configuration> 10 </plugin> 11 <plugin> 12 <groupId>org.apache.maven.plugins</groupId> 13 <artifactId>maven-shade-plugin</artifactId> 14 <executions> 15 <execution> 16 <phase>package</phase> 17 <goals> 18 <goal>shade</goal> 19 </goals> 20 </execution> 21 </executions> 22 </plugin> 23 <plugin> 24 <groupId>org.apache.thrift.tools</groupId> 25 <artifactId>maven-thrift-plugin</artifactId> 26 <version>0.1.11</version> 27 <configuration> 28 <thriftSourceRoot>src/main/if</thriftSourceRoot> 29 </configuration> 30 <executions> 31 <execution> 32 <id>thrift-sources</id> 33 <phase>generate-sources</phase> 34 <goals> 35 <goal>compile</goal> 36 </goals> 37 </execution> 38 </executions> 39 </plugin> 40 <plugin> 41 <groupId>org.apache.maven.plugins</groupId> 42 <artifactId>maven-compiler-plugin</artifactId> 43 <configuration> 44 <source>1.8</source> 45 <target>1.8</target> 46 <encoding>UTF-8</encoding> 47 </configuration> 48 </plugin> 49 </plugins> 50 </build>
和
1 <!--thrift--> 2 <dependency> 3 <groupId>org.apache.thrift</groupId> 4 <artifactId>libthrift</artifactId> 5 <version>0.11.0</version> 6 </dependency>
最后maven編譯即可
最后可以從target目錄下看到編譯好的java文件:
注:IDEA編譯的話,也需要安裝thrift插件(參見:https://www.cnblogs.com/lcmichelle/p/10743081.html)
十一、反編譯代碼
1. 反編譯工具Jadx
安裝好之后找到編譯好的jadx-gui可執行文件運行
比如目錄下:/Users/admin/jadx/build/jadx/bin/jadx-gui
十二、集合
1. 迭代器的使用
使用迭代器可以邊訪問集合邊刪除元素
Iterator<String> iterator = all.iterator();//實例化迭代器 while(iterator.hasNext()){ String str=iterator.next();//讀取當前集合數據元素 if("b".equals(str)){ //all.remove(str);//使用集合當中的remove方法對當前迭代器當中的數據元素值進行刪除操作(注:此操作將會破壞整個迭代器結構)使得迭代器在接下來將不會起作用 iterator.remove(); }else{ System.out.println( str+" "); } }
十三、單元測試
1. jacoco工具
最近用了jacoco工具,感覺挺好使的,單元測試當然也可以使用IDE自帶的run with coverag。Jacoco有命令行和Pom配置兩種方式,命令行方式就是在工程根目錄下執行以下命令,如果多個模塊可以到子模塊下執行:
1 mvn clean test org.jacoco:jacoco-maven-plugin:0.7.4.201502262128:prepare-agent install -Dmaven.test.failure.ignore=true
然后在target文件下生成jacoco-ut文件夾,文件夾下可以看到index.html文件,用瀏覽器打開就是單元覆蓋率報告。
另一種方式就是Pom配置文件的方式,注意dataFile和outputDirectory一定要寫清楚,另外一定要有test/java這個目錄
1 <dependency> 2 <groupId>org.testng</groupId> 3 <artifactId>testng</artifactId> 4 <version>6.9.6</version> 5 <scope>test</scope> 6 <optional>true</optional> 7 </dependency> 8 <dependency> 9 <groupId>org.jacoco</groupId> 10 <artifactId>jacoco-maven-plugin</artifactId> 11 <version>0.7.4.201502262128</version> 12 <scope>test</scope> 13 </dependency> 14 <dependency> 15 <groupId>junit</groupId> 16 <artifactId>junit</artifactId> 17 <version>4.12</version> 18 <scope>test</scope> 19 </dependency>
1 <plugin> 2 <groupId>org.apache.maven.plugins</groupId> 3 <artifactId>maven-shade-plugin</artifactId> 4 <version>2.4.1</version> 5 <executions> 6 <!-- Run shade goal on package phase --> 7 <execution> 8 <phase>package</phase> 9 <goals> 10 <goal>shade</goal> 11 </goals> 12 <configuration> 13 <!--<relocations>--> 14 <!--<relocation>--> 15 <!--<pattern>com.google.protobuf</pattern>--> 16 <!--<shadedPattern>shaded.com.google.protobuf</shadedPattern>--> 17 <!--</relocation>--> 18 <!--</relocations>--> 19 <filters> 20 <filter> 21 <artifact>org.apache.flink:*</artifact> 22 <excludes> 23 <!-- exclude shaded google but include shaded curator --> 24 <exclude>org/apache/flink/shaded/com/**</exclude> 25 <exclude>web-docs/**</exclude> 26 </excludes> 27 </filter> 28 <filter> 29 <!-- Do not copy the signatures in the META-INF folder. 30 Otherwise, this might cause SecurityExceptions when using the JAR. --> 31 <artifact>*:*</artifact> 32 <excludes> 33 <exclude>META-INF/*.SF</exclude> 34 <exclude>META-INF/*.DSA</exclude> 35 <exclude>META-INF/*.RSA</exclude> 36 </excludes> 37 </filter> 38 </filters> 39 <createDependencyReducedPom>false</createDependencyReducedPom> 40 </configuration> 41 </execution> 42 </executions> 43 </plugin> 44 45 <plugin> 46 <groupId>org.apache.maven.plugins</groupId> 47 <artifactId>maven-compiler-plugin</artifactId> 48 <version>3.1</version> 49 <configuration> 50 <source>1.8</source> <!-- If you want to use Java 8, change this to "1.8" --> 51 <target>1.8</target> <!-- If you want to use Java 8, change this to "1.8" --> 52 </configuration> 53 </plugin> 54 <plugin> 55 <groupId>org.apache.maven.plugins</groupId> 56 <artifactId>maven-surefire-plugin</artifactId> 57 <version>2.19</version> 58 <configuration> 59 <!--<argLine>-Xmx256M ${jacocoArgLine}</argLine> --> 60 <!--<skip>false</skip> --> 61 <!--<testFailureIgnore>false</testFailureIgnore> --> 62 <!--<includes></includes>--> 63 <!--<includes>--> 64 <!--<include>**/*Test.java</include>--> 65 <!--</includes>--> 66 <!--<argLine>-XX:-UseSplitVerifier</argLine>--> 67 </configuration> 68 </plugin> 69 70 <plugin> 71 <groupId>org.jacoco</groupId> 72 <artifactId>jacoco-maven-plugin</artifactId> 73 <version>0.7.4.201502262128</version> 74 <configuration> 75 <!--<includes>--> 76 <!--<include>com/src/**/*</include>--> 77 <!--</includes>--> 78 </configuration> 79 <executions> 80 <execution> 81 <id>pre-test</id> 82 <goals> 83 <goal>prepare-agent</goal> 84 </goals> 85 <configuration> 86 <propertyName>jacocoArgLine</propertyName> 87 </configuration> 88 </execution> 89 <execution> 90 <id>post-test</id> 91 <phase>test</phase> 92 <goals> 93 <goal>report</goal> 94 </goals> 95 </execution> 96 <execution> 97 <id>post-unit-test</id> 98 <phase>test</phase> 99 <goals> 100 <goal>report</goal> 101 </goals> 102 <configuration> 103 <dataFile>/Users/admin/Desktop/test/target/jacoco.exec</dataFile> 104 <outputDirectory>/Users/admin/Desktop/test/target/target/jacoco-u</outputDirectory> 105 </configuration> 106 </execution> 107 </executions> 108 </plugin>
十四、Protobuf
1. Protobuf里的數組
Protobuf文件中使用repeated定義數組類型元素,Java設置的時候使用addEntitites而不是set
十五、Maven
1. -DskipTests和-Dmaven.test.skip=true跳過單元測試
mvn clean package -DskipTests,不執行測試用例,但編譯測試用例類生成相應的class文件至target/test-classes下。
mvn clean package -Dmaven.test.skip=true,不執行測試用例,也不編譯測試用例類
2. 本地倉庫導入官方倉庫沒有的jar包
用到Maven如下命令:
mvn install:install-file
-DgroupId=包名
-DartifactId=項目名
-Dversion=版本號
-Dpackaging=jar
-Dfile=jar文件所在路徑
比如執行以下命令:
mvn install:install-file -Dfile=D:\lib\jnotify-0.94.jar -DgroupId=net.contentobjects -DartifactId=jnotify -Dversion=0.94 -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true
工程中使用時在pom.xml中添加如下內容:
<dependency> <groupId>net.contentobjects</groupId> <artifactId>jnotify</artifactId> <version>0.94</version> <<type>jar</type> </dependency>
十六、日志打印
1. 異常打印
/** * String getMessage() :返回此 throwable 的詳細消息字符串。 * String toString() : 返回此 throwable 的簡短描述。 * void printStackTrace():將此 throwable 及其追蹤輸出至標准錯誤流。 (即 調用此方法會把完整的異常信息打印到控制台) * @author 鄭清 */ public class Demo { public static void main(String[] args) { test(6,0); } public static void test(int a,int b){ try{ System.out.println(a/b); }catch(Exception e){ //catch里面是出現異常的處理方式 下面err是以紅色打印信息 System.err.println(e.getMessage());//打印異常原因 ==》 一般給用戶看 System.err.println(e.toString());//打印異常名稱以及異常原因 ==》 很少使用 e.printStackTrace();//打印異常原因+異常名稱+出現異常的位置 ==》 給程序員debug的時候看 } System.out.println("===try-catch結束==="); } }