每日碎屑- 2025-02-21

16 阅读1分钟

<1> Arrays.copyOf() 

copyOf,复制指定的数组,截取或用 null 填充 

<2> about equals() 

Use Arrays.equals() for one-dimensional or primitive arrays. 

Use Arrays.deepEquals() for multi-dimensional arrays or arrays of objects to ensure a deep comparison. 

<3> 对于fibonacci 

可以使用Arrays.parallelPrefix(arr, Integer::sum), 然后获取最后一个元素 

或者使用 list.stream().reduce(Integer::sum); 

<4> Optional orElse() vs orElseGet() 

Usage on orElseGet() : Similar to orElse, but instead of a direct value, it takes a Supplier that gets invoked only if the Optional is empty. 

Evaluation: The Supplier is evaluated only when the value is absent, making it more efficient for expensive operations. 

Use orElse when you have a constant or inexpensive value to return. 

Use orElseGet when you want to defer the computation of the default value until it's actually needed, especially if the default value involves a costly operation. 

<5> @SafeVarargs 

When to Use: Use @SafeVarargs when you are sure that the method does not modify the contents of the varargs parameter or expose it in a way that could lead to heap pollution.  

Limitations: Only applicable to static methods or instance methods of final classes. Using it in non-final instance methods can still lead to heap pollution, which is why the annotation is restricted.

About combine all predicates

    @SafeVarargs
    private static <T> Predicate<T> multiFilter(Predicate<T>... predicates) {
        return t -> {
            for(Predicate<T> predicate : predicates) {
                if(!predicate.test(t)) {
                    return false;
                }
            }
            return true;
        };
    }

    @SafeVarargs
    private static <T> Predicate<T> multiFilters(Predicate<T>... predicates) {
        return t -> Stream.of(predicates).allMatch(predicate -> predicate.test(t));
    }

<6> 加载类

    @SneakyThrows
    private static void getClassName() {
        Class<?> clazz1 = Class.forName("com.trading.experimental.reflection.MyClass");
        System.out.println(clazz1.getName());           // com.trading.experimental.reflection.MyClass
        System.out.println(clazz1.getCanonicalName());  // com.trading.experimental.reflection.MyClass

        //double[]
        Class<?> clazz2 = Class.forName("[D");
        System.out.println(clazz2.getName());            //  [D
        System.out.println(clazz2.getCanonicalName());   //  double[]

        //String[][]
        Class<?> clazz3 = Class.forName("[[Ljava.lang.String;");
        System.out.println(clazz3.getName());            //  [[Ljava.lang.String;
        System.out.println(clazz3.getCanonicalName());   //  java.lang.String[][]

        Class<?> clazz4 = int[][][].class;
        System.out.println(clazz4.getName());            //  [[[I
        System.out.println(clazz4.getCanonicalName());   //  int[][][]
    }

 <7> 编码问题

    public static void test1() {
        String originalStr = "沉默王二";
        String encodedStr = "";

        try {
            byte[] bytes = originalStr.getBytes("GBK");
            encodedStr = new String(bytes, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        System.out.println("转码前: " + originalStr);
        System.out.println("转码后: " + encodedStr);
    }

    private static void test2() {
        //解决中文乱码问题需要确保在编码和解码过程中使用相同的字符编码
        String originalStr = "沉默王二";
        byte[] bytes = originalStr.getBytes(StandardCharsets.UTF_8);
        String encodedStr = new String(bytes, StandardCharsets.UTF_8);

        System.out.println("正确转码前: " + originalStr);
        System.out.println("正确转码后: " + encodedStr);
    }

输出:
转码前: 沉默王二
转码后: ��Ĭ����
正确转码前: 沉默王二
正确转码后: 沉默王二

<8> try-with-resource

有两点好处:

1. 使用完毕后会自己关闭资源,语法糖,实际上编译增加了finally block

2. 不会swallow exception, 例如

class MyfinallyReadLineThrow {
    public void close() throws Exception {
        throw new Exception("close");
    }

    public void readLine() throws Exception {
        throw new Exception("readLine");
    }
}

运行上述代码后,错误堆栈如下所示:Exception in thread "main" java.lang.Exception: close
	at com.MyfinallyOutThrow.close(TryfinallyCustomOutThrow.java:17)
	at com.TryfinallyCustomOutThrow.main(TryfinallyCustomOutThrow.j

readLine() 方法的异常信息竟然被 close() 方法的堆栈信息吃了,而使用try-with-resource则可以解决该问题

又例如

class MyResourceOut implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("close resources");
    }

    public void out() throws Exception{
        System.out.println("output demo");
    }
}

我们在 try 中调用一下 out() 方法。”

public class TrywithresourcesCustomOut {
    public static void main(String[] args) {
        try (MyResourceOut resource = new MyResourceOut();) {
            resource.out();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

反编译后的字节码为:

public class TrywithresourcesCustomOut {
    public TrywithresourcesCustomOut() {
    }

    public static void main(String[] args) {
        try {
            MyResourceOut resource = new MyResourceOut();

            try {
                resource.out();
            } catch (Throwable var5) {
                try {
                    resource.close();
                } catch (Throwable var4) {
                    var5.addSuppressed(var4);
                }

                throw var5;
            }

            resource.close();
        } catch (Exception var6) {
            var6.printStackTrace();
        }

    }
}

这次,catch 块主动调用了 resource.close(),并且有一段很关键的代码 var5.addSuppressed(var4)

当一个异常被抛出的时候,可能有其他异常因为该异常而被抑制住,从而无法正常抛出。这时可以通过 addSuppressed() 方法把这些被抑制的方法记录下来,然后被抑制的异常就会出现在抛出的异常的堆栈信息中,可以通过 getSuppressed() 方法来获取这些异常。这样做的好处是不会丢失任何异常,方便我们进行调试

再次尝试运行

class MyResourceOutThrow implements AutoCloseable {
    @Override
    public void close() throws Exception {
        throw  new Exception("close()");
    }

    public void out() throws Exception{
        throw new Exception("out()");
    }
}

调用这 2 个方法

public class TrywithresourcesCustomOutThrow {
    public static void main(String[] args) {
        try (MyResourceOutThrow resource = new MyResourceOutThrow();) {
            resource.out();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

程序输出的结果如下所示

java.lang.Exception: out()
	at com.MyResourceOutThrow.out(TrywithresourcesCustomOutThrow.java:20)
	at com.TrywithresourcesCustomOutThrow.main(TrywithresourcesCustomOutThrow.java:6)
	Suppressed: java.lang.Exception: close()
		at com.MyResourceOutThrow.close(TrywithresourcesCustomOutThrow.java:16)
		at com.TrywithresourcesCustomOutThrow.main(TrywithresourcesCustomOutThrow.java:5)