工具篇-Java中一些utils

工具篇-Java中一些utils

下边是整理的一些Java开发的utils,顺便吐槽下新浪博客的编辑器排版跟我写的博客一样 烂,所以改用博客园

一、字符串

1. Java中String与其他类型之间的转换

  • String与日期对象

 public static SimpleDateFormat df1 = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss", Locale.US);
public static SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
df2.format(df1.parse(time_local));
在将字符串转为日期对象时,可以使用parse方法;日期对象转为字符串时,可以使用format方法。但是parse在解析日期字符串的时候本身存在一些问题:比如https://blog.csdn.net/a158123/article/details/54292268
  • String与八种基本类型(以int为例)

String转int:
 try {
int i = Integer.parseInt(str);
} catch (NumberFormatException e) { //str中可能有非数字
e.printStackTrace();
}
int转String:
第一种方法:
  str=i+""; //会产生两个String对象 
第二种方法:
  str=String.valueOf(i); //直接使用String类的静态方法,只产生一个String对象 

2. 去掉字符串前面的0

  • 使用replaceAll(正则或者目标字符串,要替换上的字符串)
 String str = "000000001234034120";
String newStr = str.replaceAll("^(0+)", "");
System.out.println(newStr);

这里说明下replace和replaceAll的区别:replace的参数是char和CharSequence,即可以支持字符的替换,也支持字符串的替换;replaceAll的参数是regex,即基于正则表达式的替换。

  • 使用replaceFirst(正则或者目标字符串,要替换上的字符串)
 String str = "000000001234034120";
String newStr = str.replaceFirst("^(0+)", "");
System.out.println(newStr);

3. String.format方法

 String formatted = String.format("%s今年%d岁。", "我", 25); // 打印结果:"我今年25岁。"
第一个参数是格式串,后面参数都是格式串的参数,用于替换格式串中的占位符。占位符类型有下面几种:(大写表示输出为大写)
工具篇-Java中一些utils

3. String == 和equals方法

  • “==”判断的是地址值,equals()方法判断的是内容

 str1.equals(str2)
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 注解

  • 指定字段的名称

 @JSONField(name="role_name")
private String roleName;
  • 使用format制定日期格式

public class A {
// 配置date序列化和反序列使用yyyyMMdd日期格式
@JSONField(format="yyyyMMdd")
public Date date;
}
  • 指定字段的顺序

 public static class VO {
@JSONField(ordinal = 3)
private int f0; @JSONField(ordinal = 2)
private int f1; @JSONField(ordinal = 1)
private int f2;
  • 使用serialize/deserialize指定字段不序列化

 public class A {
@JSONField(serialize=false)
public Date date;
}

三、随机数

1. Java中产生随机数的方法
  • 使用Random类

Random类可以产生 boolean、int、long、float, byte 数组以及 double 类型的随机数,这是它与 random()方法最大的不同之处,random()方法只能产生double类型的 0~1的随机数。
Random 类位于 java.util 包中,该类常用的有如下两个构造方法。
Random():该构造方法使用一个和当前系统时间对应的数字作为种子数,然后使用这个种子数构造 Random 对象。
Random(long seed):使用单个 long 类型的参数创建一个新的随机数生成器。例如:

 public static void main(String[] args)
{
Random r=new Random();
double d1=r.nextDouble(); //生成[0,1.0]区间的小数
double d2=r.nextDouble()*7; //生成[0,7.0]区间的小数
int i1=r.nextInt(10); //生成[0,10]区间的整数
int i2=r.nextInt(18)-3; //生成[-3,15]区间的整数
long l1=r.nextLong(); //生成一个随机长整型值
boolean b1=r.nextBoolean(); //生成一个随机布尔型值True或者False
float f1=r.nextFloat{); //生成一个随机浮点型值
}
  • Math类的random()方法

该方法没有参数,它默认会返回大于等于0.0、小于1.0的double类型随机数。如下:

 public static void main(String[] args)
{
int min=0; //定义随机数的最小值
int max=100; //定义随机数的最大值
//产生一个1~100的数
int s=(int)min+(int)(Math.random()*(max-min));
}
2. Java生成UUID
UUID 的目的是让分布式系统中所有元素都有唯一辨识资讯,而不需要由*控制端来做辨识资讯的指定。
UUID由以下几部分的组成:
  • 当前日期和时间
  • 时钟序列
  • 全局唯一的IEEE机器识别号,如果有网卡,从网卡MAC地址获得,没有网卡以其他方式获得。
      UUID的唯一缺陷在于生成的结果串会比较长。关于UUID这个标准使用最普遍的是微软的GUID(Globals Unique Identifiers)。标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12)。
UUID 来作为数据库数据表主键是非常不错的选择,保证每次生成的UUID 是唯一的。
      //获得指定数目的UUID
public static String[] getUUID(int number){
if(number < 1){
return null;
}
String[] retArray = new String[number];
for(int i=0;i){
retArray[i] = getUUID();
}
return retArray;
}
//获得一个UUID
public static String getUUID(){
String uuid = UUID.randomUUID().toString();
//去掉“-”符号
return uuid.replaceAll("-", "");
}

四、文件

1. FileUtils

具有封装的读写文件、复制文件等功能。例如:

 import org.apache.commons.io.FileUtils;
List lines = new ArrayList();
...
FileUtils.writeLines(new File("/Users/admin/1.txt"), lines, true);
String result = FileUtils.readFileToString(new File("/Users/admin/1.txt"), "UTF-8");

2. 配置文件读取

一般情况下,我们用到的资源文件(各种xml,properites,xsd文件等)都放在src/main/resources下面,利用maven打包时,maven能把这些资源文件打包到相应的jar或者war里。在程序中就可以直接读取了,例如:
  • properties文件

 InputStream input =Thread.currentThread().getContextClassLoader().getResourceAsStream("abc.properties");
Properties prop = new Properties();
prop.load(input);
  • yaml文件

 InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(yamlPath);
Yaml yaml = new Yaml();
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及以上)

六、网络

1. 主机名转IP

 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()可以知道该对象被移除的原因

 public enum RemovalCause {
//用户手动移除
EXPLICIT,
//用户手动替换
REPLACED,
//被垃圾回收
COLLECTED,
//超时过期
EXPIRED,
//由于缓存大小限制
SIZE;
}

八、日期

1. TimeUnit

TimeUnit提供了各种时间方法,比如常用的toMillis、toNaNos、sleep(Long timeout)等等,可读性极高,使用方便且性能也不错,具体使用方法参考:Java-TimeUnit类常用方法详解,对比一下:

 // TimeUnit
TimeUnit.MILLISECONDS.sleep(10);
TimeUnit.SECONDS.sleep(10);
TimeUnit.MINUTES.sleep(10); // 原生Thread方法
Thread.sleep(10);
Thread.sleep(10*1000);
Thread.sleep(10*60*1000); 

2. Java8只取年月日的java.util.Date(时分秒清零)对象

 // set current date
date = new Date();
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date);
// clear minute second milliSecond
cal1.set(Calendar.MINUTE, 0);
cal1.set(Calendar.SECOND, 0);
cal1.set(Calendar.MILLISECOND, 0);
date = cal1.getTime();

3. java.util.Date转java.sql.Date

 Date utilDate = new Date();//uilt.Date
System.out.println("utilDate : " + utilDate);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("format : " + format.format(utilDate)); System.out.println("**********************************************"); Timestamp sqlDate = new Timestamp(utilDate.getTime());//uilt.Date转sql.Date
System.out.println("sqlDate : " + sqlDate);
System.out.println("format : " + format.format(sqlDate));

工具篇-Java中一些utils

九、代码规范

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
 if (condition) {
// do something
} else {
return xxx;
}

这种情况条件取反,干掉else

 if (!condition) {
return xxx;
} // do something
  • 策略模式

有种情况是根据不同的参数走不同的逻辑,先看一般写法:

 if (strategy.equals("fast")) {
// 快速执行
} else if ("strategy.equals("normal")) {
// 正常执行
} else if ("strategy.equals("smooth")) {
// 平滑执行
} else if ("strategy.equals("slow")) {
// 慢慢执行
}

其实可以用枚举

 public enum Stategy {
FAST{
@Override
public void run() {
System.out.println("fast---");
}
},
NORMAL{
@Override
public void run() {
System.out.println("normal---");
}
},
SMOOTH{
@Override
public void run() {
System.out.println("smooth---");
}
},
SLOW {
@Override
public void run() {
System.out.println("slow---");
}
}; public abstract void run();
}

最后,可以通过param执行不同逻辑

 Strategy strategy = Strategy.valueOf(param);
Strategy.run();
  • 用Optional

jdk8新特性,主要用于非空判断

 if (user == null) {
// do action 1
} else {
// do action2
}

可以改为

 Optional<User> userOptional =  Optional.ofNullable(user);
userOptional.map(action1).orElse(action2); 

十、thrift

1. thrift文件的使用

最近看别人的老项目用到了thrift文件,以前没用过,挺好玩的,记录一下。刚开始从gitlab上clone下来以后,会发现有些包会爆红:

工具篇-Java中一些utils

同时src目录下有thrift文件

工具篇-Java中一些utils

问了下同事说是要compile一下,还得先安装0.9.3的thrift(还有一些插件,一定要*,如果没有全局设置的话,需要在shell里边重新设置下)

 export http_proxy=http://127.0.0.1:1087; export https_proxy=http://127.0.0.1:1087

工程里修改pom文件

 <build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.thrift.tools</groupId>
<artifactId>maven-thrift-plugin</artifactId>
<version>0.1.11</version>
<configuration>
<thriftSourceRoot>src/main/if</thriftSourceRoot>
</configuration>
<executions>
<execution>
<id>thrift-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>

  <!--thrift-->
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.11.0</version>
</dependency>

最后maven编译即可

工具篇-Java中一些utils

最后可以从target目录下看到编译好的java文件:

工具篇-Java中一些utils

注:IDEA编译的话,也需要安装thrift插件(参见:https://www.cnblogs.com/lcmichelle/p/10743081.html

十一、反编译代码

1. 反编译工具Jadx

安装好之后找到编译好的jadx-gui可执行文件运行
比如目录下:/Users/admin/jadx/build/jadx/bin/jadx-gui

工具篇-Java中一些utils

十二、集合

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配置两种方式,命令行方式就是在工程根目录下执行以下命令,如果多个模块可以到子模块下执行:

 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文件,用浏览器打开就是单元覆盖率报告。

工具篇-Java中一些utils

工具篇-Java中一些utils

另一种方式就是Pom配置文件的方式,注意dataFile和outputDirectory一定要写清楚,另外一定要有test/java这个目录

             <dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.6</version>
<scope>test</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.4.201502262128</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
         <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<executions>
<!-- Run shade goal on package phase -->
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<!--<relocations>-->
<!--<relocation>-->
<!--<pattern>com.google.protobuf</pattern>-->
<!--<shadedPattern>shaded.com.google.protobuf</shadedPattern>-->
<!--</relocation>-->
<!--</relocations>-->
<filters>
<filter>
<artifact>org.apache.flink:*</artifact>
<excludes>
<!-- exclude shaded google but include shaded curator -->
<exclude>org/apache/flink/shaded/com/**</exclude>
<exclude>web-docs/**</exclude>
</excludes>
</filter>
<filter>
<!-- Do not copy the signatures in the META-INF folder.
Otherwise, this might cause SecurityExceptions when using the JAR. -->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source> <!-- If you want to use Java 8, change this to "1.8" -->
<target>1.8</target> <!-- If you want to use Java 8, change this to "1.8" -->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<!--<argLine>-Xmx256M ${jacocoArgLine}</argLine> -->
<!--<skip>false</skip> -->
<!--<testFailureIgnore>false</testFailureIgnore> -->
<!--<includes></includes>-->
<!--<includes>-->
<!--<include>**/*Test.java</include>-->
<!--</includes>-->
<!--<argLine>-XX:-UseSplitVerifier</argLine>-->
</configuration>
</plugin> <plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.4.201502262128</version>
<configuration>
<!--<includes>-->
<!--<include>com/src/**/*</include>-->
<!--</includes>-->
</configuration>
<executions>
<execution>
<id>pre-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<propertyName>jacocoArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>post-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>/Users/admin/Desktop/test/target/jacoco.exec</dataFile>
<outputDirectory>/Users/admin/Desktop/test/target/target/jacoco-u</outputDirectory>
</configuration>
</execution>
</executions>
</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结束===");
}
}

 工具篇-Java中一些utils 

上一篇:sharedevelop iis express


下一篇:DevExpress v17.2—WPF篇(一)