语句
swich语句
switch(表达式){
case 常量表达式1:
语句1;
break;
default:
语句;
}
循环优化
1. iterator、for循环、foreach循环之间的性能没有区别,为保持业务代码简洁和可读性,可以放心使用foreach。
2. 匿名类在编译期会创建一个类文件,有链接和加载的性能成本,影响代码发布性能。且在线上每个请求调用时都会创建一个匿名类对象,
占用内存空间,初始化和gc也消耗cpu性能,这个成本是不必要的,IDEA通常都会建议改成lambda表达式,不推荐使用匿名类。
3. lambda表达式本质是在编译器生成一个类的静态私有方法,在运行时通过invokedynamic命令调用,因此不会明显劣化性能。
反而lambda表达式配合foreach循环使用,能提高些许性能,虽然提升幅度不大,这应该与不用分配局部变量有关系,推荐使用lambda表达式。
4. for循环和foreach+lambda性能都比stream+lambda性能好得多,说明stream才是导致性能下降的主因。
stream在复杂逻辑处理和大数据量下性能和for循环可以做到一个数量级(某些测试博客的结果),但在某些业务的数据量下,流式转换操作性能消耗略大,不如for循环。
但是stream在编码简洁和可读性上明显优于for循环,因此在性能不是特别敏感的场景下或业务逻辑转成for循环可读性差时,可以酌情使用stream流式操作。
5. parallelStream在我们常用的数据量下,性能比stream更差,不推荐使用。parallelStream底层使用到了ForkJoinPool,在op内对小数据量级进行并行化操作,会引入大量的线程上下文切换, 这个消耗比并行化的收益更大。
Java 基本数据类型最大值极限和最小值极
public static void main(String[] args) {
System.out.println("Integer.MIN_VALUE = " + Integer.MIN_VALUE);
System.out.println("Integer.MAX_VALUE = " + Integer.MAX_VALUE);
System.out.println("Long.MIN_VALUE = " + Long.MIN_VALUE);
System.out.println("Long.MAX_VALUE = " + Long.MAX_VALUE);
System.out.println("Float.MIN_VALUE = " + Float.MIN_VALUE);
System.out.println("Float.MIN_NORMAL = " + Float.MIN_NORMAL);
System.out.println("Float.MAX_VALUE = " + Float.MAX_VALUE);
System.out.println("Double.MAX_VALUE = " + Double.MAX_VALUE);
System.out.println("Double.MIN_VALUE = " + Double.MIN_VALUE);
}
除法
整数除法
1 整数间的除法运算,只返回整数位。
因为在Java中,由运算结果,由被运算数的最高数据类型决定,也就是说:整数之间的运算,数据类型都为int类型,所以,返回的结果也为int类型。
解决:(float)inta / intb;
inta/2f
2 Float或Double与一个整数做除法运算,则商位Float或者Double类型。
3 0在整数预算中不可以做除数,否则抛运行时异常。
4 0在浮点运算中可以做除数,返回值为无穷大。浮点型(Float或Double)的除法运算可以接受任何数值,并且结果总是返回一个浮点型的数值。这个数值可能是不合法的,需要进行判断和验证。
5 当两个数的绝对值均为0.0时,商等于NaN。当0.0/x,x不等0.0时候,得到的一个带符号位0.0。
[Java除法运算的陷阱_51CTO博客_java除法运算]
初始化
protected double[] queueScoreList;
queueScoreList = new double[inputList.size()];
类型转换
float和double互转
float_score.setScore(double_score.floatValue());
double_score.setScore(float_score.doubleValue());
Note: 如果考虑精度问题参考[java Float和Double 之间的相互转型问题_float转double_liang_Henry的博客-CSDN博客]
Double vecrec_score = ***;
docInfo.setScore(vecrec_score.floatValue());
json中的int转long
Both Integer and Long are subclasses of Number.
long ipInt = ((Number) jsonobj.get("ipInt")).longValue();
Long.valueOf(jsonobj.get("ipInt").toString());
[casting - java.lang.Integer cannot be cast to java.lang.Long - Stack Overflow]
字符串转int类型
Integer.valueOf
其它类型转成字符串
String c = String.valueOf(3.2133535);
String str = String.valueOf(ch) 或者 char c = 'a'; String s = "" + c;
String和集合类型如List类型互转
[Java集合和字符串操作_-柚子皮-的博客-CSDN博客]
[https://youzipi.blog.csdn.net/article/details/43303145]
JAVA中对null进行强制类型转换
[JAVA中对null进行强制类型转换_null可以强转为string吗_不作死就不会si的博客-CSDN博客]
保留小数位数
保留两位小数
String a = new DecimalFormat("######0.00").format(a);
java浮点数保留n位小数
import java.text.DecimalFormat;
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.t7();
}
public void t7() {
double d = 1252.2563;
String st = new DecimalFormat(".00").format(d);
System.out.println(st);
}
}
1252.25
Note: ".00"中的n个0就代表多少位小数;也可以使用DecimalFormat(".##").format(d),只是如果小数后面是0的话会省略,如12.50会变成12.5。
类
获取当前类名:
String className = Thread.currentThread().getStackTrace()[1].getClassName(); //1可改
[Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别]
其它方法[Java获取当前类名、方法名_veryoldman的博客-CSDN博客]
函数
常用函数
Collections.binarySearch(list1, value);
Builder类型appen新特征
features = features.toBuilder().addFeature(feature).build();
自定义函数
sigmoid函数
public static double sigmoid(double x) { return 1 / (1 + Math.exp(-x)); }
java 方法设置默认值
java本身不支持设置默认值,需要用重载间接实现。
因为“默认参数”和“方法重载”同时支持的话有二义性的问题,Java可能为了简单就不要“默认参数”了。使用“方法重载”可以间接实现”默认参数“的效果,而且避免了代码过于hack(乱)。
public class A{
public void doA(int a){
}
public void doA(){
this.doA(0);//这里默认传入0,可以近似与通过这个方法重载,实现了默认值
}
}
java函数返回多个值
解决方法:
使用Pair
return new Pair<>(adIdList, adMap);
使用集合类
使用map返回值;问题是,你并不知道如何返回值的key是什么,只能通过doc或者通过源代码来查看。
使用引用传递
传入一个引用进去,修改引用的属性值。问题:不实用。
使用封装对象
通过泛型构造一个类似python的tuple类,或者构造一个JavaBean,其问题都是“一次性”,觉的不优雅。
示例:
import jodd.util.Tuple2;
private static Tuple2<double[][], Integer> func(***):
return new Tuple2<double[][], Integer>(a, b);
// 调用取值
Tuple2<double[][], Integer> proj = func(***);
double[][] a = proj.v1();
Integer b = proj.v2();
使用EnumMap
EnumMap作为返回值类型,自己定义一个enum,将可能返回的属性名定义为enum取值即可。
优点:
1.反参可以是多个值。
2.通过枚举(最好定义在base中),同一家公司内部,以此方式作为返回值的服务,基本不用看javadoc或者api文档,就知道出参有哪些了。
接口:
public interface TestService {
enum UserInfoProperty {
ROOM,CELLPHONE,Name
}
public EnumMap<UserInfoProperty,Object> getUserInfoByName(String name);
}
实现:
public class TestServiceImpl implements TestService {
@Override
public EnumMap<UserInfoProperty, Object> getUserInfoByName(String name) {
EnumMap<UserInfoProperty,Object> retMap = new EnumMap<UserInfoProperty, Object>(UserInfoProperty.class);
retMap.put(UserInfoProperty.ROOM,"0003");
retMap.put(UserInfoProperty.CELLPHONE,"00004");
retMap.put(UserInfoProperty.Name,name);
return retMap;
}
}
调用:
public class App
{
public static void main( String[] args )
{
TestService testService = new TestServiceImpl();
String name = "testName";
EnumMap<TestService.UserInfoProperty,Object> userInfo = testService.getUserInfoByName(name);
userInfo.entrySet().iterator();
System.out.println(userInfo.get(TestService.UserInfoProperty.Name));
System.out.println(userInfo.get(TestService.UserInfoProperty.ROOM));
System.out.println(userInfo.get(TestService.UserInfoProperty.CELLPHONE));
}
}
并行算分
int batch = inputList.size() % 2000 == 0 ? inputList.size() / 2000 : inputList.size() / 2000 + 1;
int avgBatchSize = inputList.size() / batch;
IntStream.range(0, batch).parallel()
.forEach(batchK -> {
int start = batchK * avgBatchSize;
int end = batchK == batch - 1 ? inputList.size() : (batchK + 1) * avgBatchSize;
for (int i = start; i < end; i++) {
scoreList[i] = func(inputList.get(i));
}
});
获取异常的堆栈信息
通过e.getMessage()
获取异常信息,内容常常显示不全,而且有时候为空。
public static String getStackTrace(Throwable throwable) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
try{
throwable.printStackTrace(pw);
return sw.toString();
} finally{
pw.close();
}
}
public static void test() {
try {
} catch (Exception e){
System.out.println(e.getMessage());
System.out.println(getStackTrace(e));
}
}
文件路径操作
路径合并:Path path = Paths.get("foo", "bar", "baz.txt");
String file = Paths.get(DIR, hdfs_filename).toString();
from:-柚子皮-
ref: