Skip to content

JAVA问题集:找寻问题的答案

About 1412 wordsAbout 5 min

java问题集

2024-08-01

记录自己在使用Java过程中遇到的问题,看下去,说不定一也有相同问题,能够找到解决办法。

推荐B站上看到的好的视频:

一、字符串(String)

1.1、数字转化成指定位数的字符串,不足的进行补零

java将数字转换为指定位数的字符串

1.1.1、String.format()方法转换

String.format("%04d", 22);  // "0022"
String.format("%05d", 22);  // "00022"

0代表前面要补的字符, 4表示字符串的长度, d表示参数为整数类型。

1.1.2、DecimalFormat类转换

DecimalFormat df = new DecimalFormat("0000");  // 0的位数表示最后输出位数
String result = df.format(22); // "0022"

"0000"表示将数据格式化为4位长度的字符串,不足4位时使用0填充,超过4位不做处理。

1.1.3、StringBuilder类拼接字符串

int len = 4, num = 22;
StringBuilder sb = new StringBuilder();
sb.append(num);
while(sb.length()<len){
  sb.insert(0, "0");
}
String result = sb.toString();

二、日期(Date,Calendar)

2.1、获取到日期的年月日

三、进制

3.1、10进制与2进制转换

  • 10进制转2进制字符
String string = Integer.toString(10, 2);  // 1010
String binaryString = Integer.toBinaryString(10);  // 1010
  • 2进制字符转10进制

    • 使用java的API实现
    int num = Integer.parseInt(binaryString, 2);
    • 手写转换
    public int convert(String binary) {
        // 1101 -> 1 * 2 ^ 0 + 0 * 2 ^ 1 + 1 * 2 ^ 2 + 1 * 2 ^ 3
        int len = binary.length();
        int ans = 0;
        for (int i = 0; i < len; i++) {
            int n = binary.charAt(len - i - 1) - '0';
            /// 1 << i 表示 Math.pow(2, i)
            ans += n * (1 << i);
        }
        return ans;
    }
int i = 1 << 2; // 4 左移操作,等价于 Math.pow(2, 2) = 4

四、数据类型

4.1、Map

4.1.1、将Map的values转化成List

HashMap#values() 返回的是一个java.util.Collection\<V>, 并不能强制转化到ArrayList中。

需要new ArrayList(HashMap.values())

4.1.2、Collector.toMap()

toMap方法在有多个key的时候,会报错,这个时候可以使用toMap(key, value, (o, n) -> n);直接返回新值。

Java 数据长度获取方式对比:length属性、length()和size()方法

字符串使用cha r[]实现的,字符串提供了一个length()的方法,用来获取char[]数组的长度

private final char value[];
public int length() {
    return value.length;
}

数组的话,默认有一个length的属性,可以直接调用。

集合的话,维护了一个size的属性,但是返回长度是用size()方法。

private int size;
public int size() {
    return size;
}

五、集合

1、求两个集合的交集

优化代码就是用小的集合来驱动大的集合。

public Set < Integer > intersection(Set < Integer > s1, Set < Integer > s2) {
    // 小的集合驱动大的集合
    boolean b = s1.size() > s2.size();
    Set < Integer > cloneSet = new HashSet < Integer > (b ? s2 : s1);
    cloneSet.retainAll(b ? s1 : s2);
    return cloneSet;
}

六、对象

1、动态的给一个对象的字段赋值

假如我有一个person的对象,我想根据列表里面定义的字段动态的添加属性值。

通过类.getDeclaredFieled(fieldName) 来获取到字段对象,setAccessible(true) 表示可访问,然后用set赋值。

需要抛出NoSuchFieldException, IllegalAccessException错误。

2、对象的深浅拷贝

自己的需求就是,从数据库里面查询出来一个对象, 需要复制一个新的对象,并修改某些字段的值,然后在存入到数据库。

还有就是第三方的拷贝库的使用。

不管是深拷贝还是浅拷贝,都是通过Object类的clone()方法来完成的。

Cloneable是一个标记接口,里面没有代码。

  • 浅拷贝:浅拷贝会在对上创建一个新的对象(区别于引用拷贝的一点),不过,如果原对象内部的属性是引用类型的话, 浅拷贝会直接复制对象的引用地址,也就是说拷贝对象和原对象公用同一个内部对象
  • 深拷贝:深拷贝会完全复制整个对象,包括这个对象所包含的内部对象。

浅拷贝,如果类中有其他类的引用,浅拷贝之后,两者都还是指向同一个,其中修改一个,之后输出都会修改。(出去字符串特殊的性质)。

深拷贝,引用类型字段也会克隆一份,当改变任何一个对象,另外一个对象不会随之改变。

通过clone方法实现过于笨重,通过序列化实现拷贝,每个要序列化的类都要实现Serializable,和Cloneable一样,是一个标记接口,没有代码。

public class PersonService {
    public void testClone() throws CloneNotSupportedException, IOException, ClassNotFoundException {
        Person person = new Person();

        // 通过Cloneable拷贝
        Person clone = (Person) person.clone();

        // 通过自定义的deepClone拷贝
        Person o = (Person) person.deepClone();
    }
}

Changelog

10/10/25, 3:04 PM
View All Changelog
  • 1ee1e-feat(wiki): algo -on

求求了,快滚去学习!!!

求求了求求了,快去学习吧!

【题单】贪心算法

不知道方向的时候,可以多看看书,书会给你指明下一步该干什么,加油!