Java: 基本语法

语句

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 四舍五入保留小数]

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。

[java使double保留两位小数的多方法]

获取当前类名:
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));
    }
}

[java方法返回多个值(用法思考、比较)]

并行算分

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();

[Combine paths in Java]

from:-柚子皮-

ref:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值