【笔记-更新中】Java相关问题

18

【推荐】循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。

特性

String

StringBuffer

StringBuilder

可变性

❌ 不可变

✅ 可变

✅ 可变

线程安全

✅ 安全(不可变)

✅ 安全(synchronized 方法)

❌ 不安全(无锁)

性能

⚠️ 最慢(频繁修改时)

⚠️ 中等(有同步锁开销)

最快(无锁,直接操作)

内存占用

高(每次修改生成新对象)

低(直接修改原对象)

低(直接修改原对象)

适用场景

字符串常量、少量拼接

多线程环境下的字符串操作

单线程环境下的字符串操作

示例

String s = "Hello";

StringBuffer sb = new StringBuffer();

StringBuilder sb = new StringBuilder();

String a = "Hello"; String b = "Hello"; 这时候boolean a == b 结果是true,有相同的字面量常量就不会再开辟新内存,除非指定了new

java的对象传参的问题:把一个对象进行传参,传的是这个对象的地址或者说是引用,这个引用是一个拷贝,但指向了这个同一个对象。这样就使得通过这个引用拷贝可以修改其关联对象的属性。但是传进去的引用本身只是个副本,只是个变量而已,对这个变量本身进行赋值,只能使得它保存另外的引用,无法影响外界。

调用方:
User user = new User("张三");  // ① 创建对象
process(user);                  // ② 传递引用
​
被调用方:
void process(User paramUser) {  // ③ 接收引用拷贝
    paramUser.setName("李四");   // ④ 修改对象
    paramUser = new User("王五");// ⑤ 改变局部引用
}

特性

说明

示例

引用拷贝

传递的是引用的副本(类似指针的拷贝)

②→③ 传递的是user引用的拷贝

对象共享

副本和原引用指向同一个堆对象

③处paramUser和user指向同一对象

属性修改可见

通过引用修改对象属性会影响原对象

④的修改会影响外部的user对象

引用隔离

对引用变量本身的赋值不影响原引用

⑤的操作不会影响外部的user变量

Arrays.asList可以将数组转为List;而list转数组没什么好办法,遍历赋值即可。

转换方向

方法

拷贝类型

特点

List转数组

toArray()

深拷贝

创建新数组,元素引用相同

List转数组

toArray(T[] a)

深拷贝

填充指定数组,元素引用相同

数组转List

Arrays.asList()

浅拷贝

包装视图,共享底层数组

数组转List

new ArrayList<>(Arrays.asList())

深拷贝

完全独立的新集合

数组转List

Arrays.stream().collect()

深拷贝

Java 8+方式,创建新集合

比较字符串相等记得要用.equals(str)

Map中使用Entry内部类来表示一个映射项,包含key和value,Map.Entry中包含getKey()和getValue()方法

entrySet是java中键值对的集合,Set里面的类型是Map.Entry,一般可以通过map.entrySet()得到。entrySet实现了Set接口,里面存放的是键值对,一个K对应一个V。可以借此来遍历map

keySet是键的集合,Set里面的类型即是key的类型

为什么很多地方只需要用到单端队列,但都用的是Deque?Deque覆盖了单队列的功能,用哪个都无所谓,索性直接用Deque就好了。在java很多实现中也都是直接用的双端队列

Deque的offer和offerlast什么区别?因为Deque是继承的Queue所以实现了offer方法然后offerLast是Deque特有

Java比较大小的时候最好还是用Integer.compare(a,b),否则有可能溢出

Java当中栈有很多实现方式,LinkedList,ArrayDeque,数组都可以模拟栈,所以其实他们的本质都是栈,实现不一样而已,其他语言同理有很多能实现的

关于Java中,基本类型比如int的数组,我们用Arrays.sort()方法进行排序时,是不支持用lambda或者Comparator去自定义比较器的,它们只支持引用类型,不支持基本数据类型。解决办法:转化为List、使用包装类数组、IntStream等。

关于List的toArray方法:Java中的List接口有两个toArray方法,一个是toArray(),一个是toArray(T[]a)。toArray()方法返回一个Object[]类型的数组,而toArray(T[]a)方法返回一个T[]类型的数组。如果传入的数组a的长度小于List中元素的个数,那么toArray(T[]a)方法会新建一个T[]类型的数组,长度为List中元素的个数,然后将List中的元素复制到新建的数组中。如果传入的数组a的长度大于等于List中元素的个数,那么toArray(T[]a)方法会将List中的元素复制到传入的数组a中,然后返回传入的数组a。toArray()方法的实现就是调用toArray(new Object[0])方法。以下示例代码为常见的使用场景,即把元素类型为int[]的List转换为二维数组