13、常用类:

news2024/11/25 16:32:47

13、常用类:

包装(Wrapper)类:

包装类的分类:

  1. 针对八种基本数据类型相应的引用类型——包装类;
  2. 有了类的特点,就可以调用类中的方法。
基本数据类型包装类
booleanBoolean
charCharacter
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble

上表中非黄色的不是Number的子类

包装类和基本数据类型的转换:

  1. jdk5 前的手动装箱和拆箱方式
    1. 装箱:基本类型 -> 包装类型;
    2. 拆箱:包装类型 -> 基本类型。
  2. jdk5后实现了自动装箱和拆箱方式;
  3. 自动装箱底层调用的式valueOf方法,比如Integer.valueOf()。
package com.jiangxian.wrapper_.integer_;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class Integer01 {
    public static void main(String[] args) {
        // jdk5以前式手动的:
        int n1 = 100;
        // jdk5以前的两种手动装箱方式:int -> Integer
        Integer integer = new Integer(n1);
        Integer integer01 = Integer.valueOf(n1);
        // 手动拆箱:
        int i = integer.intValue();

        // jdk5后自动装箱:
        int n2 = 200;
        // 自动装箱:
        Integer integer2 = n2; // 底层使用的仍然式是Integer.valueOf(n2);
        // 自动拆箱:
        int i2 = integer2; // 底层仍然使用的是 integer2.intValue();

    }
}

其余包装类是一样的,不再啰嗦举例了。

Object obj1 = true?new Integer(1):new Double(2.0); // obj1 = new Integer(1)
System.out.println(obj1);// 输出的是1.0
// 为什么?
// 三元运算符是一个整体,由于有double类型的,所以将obj设置为了Double类型。

三元运算符是一个整体!

包装类方法:

包装类和String类型的相互转换:

package com.jiangxian.wrapper_;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class WrapperVSString {
    public static void main(String[] args) {
        // 包装类 ——》String
        // 还是以Integer为例子,其余是一样的:
        Integer i = 100; // 自动装箱
        // 方式1:
        String str1 = i + "";
        // 方式2:
        String str2 = i.toString();
        // 方式3:
        String str3 = String.valueOf(i);

        //String ——》包装类(Integer)
        String str4 = "12345";
        // 方法一:
        Integer integer1 = Integer.parseInt(str4)/*返回的是一个int类型,但是会自动装箱*/;
        // 方法二:构造器
        Integer integer2 = new Integer(str4);

    }
}

所有包装类与String的转换都是一样的,所以就展示Integer这个包装类。

Integer类的常用方法:

  1. Integer.MIN_VALUE——返回最小值;
  2. Integer.MAX_VALUE——返回最大值;

Character类的常用方法:

  1. Character.isDigit(‘字符’);——判断是不是数字;
  2. Character.isLetter(‘字符’);——判断是不是字母;
  3. Character.isUpperCase(‘字符’);——判断是不是大写;
  4. Character.isLowerCase(‘字符’);——判断是不是小写;
  5. Character.isWihitespace(‘字符’);——判断是不是空格;
  6. Character.toUpperCase(‘字符’);——转换成大写;
  7. Character.toLowerCase(‘字符’);——转换成小写。

Integer创建机制:

面试题:

1:看看下面代码,输出结果是什么?为什么?

package com.jiangxian;

public class WrapperExercise02 {
    public static void main(String[] args) {
        Integer i = new Integer(1);
        Integer j = new Integer(1);
        System.out.println(i == j); // False,因为我们创建了两个不同的空间

        Integer m = 1;
        Integer n = 1;
        System.out.println(m == n); // 调用的时自动装箱,Integer.valueOf(1),得看源码
        // 源码如下:
        /*
            public static Integer valueOf(int i) {
                if (i >= IntegerCache.low && i <= IntegerCache.high)
                    return IntegerCache.cache[i + (-IntegerCache.low)];
                return new Integer(i);
            }
            我们发现里面有个判断,与IntegerCache.low和IntegerCache.high有关,
            源码中有这样的描述:This method will always cache values in the range -128 to 127
            所以我们得知IntegerCache.low = -128,IntegerCache.high = 127
         */
        // 我们发现,在-128~127这个范围,不会创建一个新的对象而是直接从缓存数组返回,所以此处为true。

        Integer x = 128;
        Integer y = 128;
        System.out.println(x == y);
        // 此处,超过了127,所以自动装箱会new一个Integer,故为false。
    }
}

2、看看下面的代码,输出声明结果?

package com.jiangxian;

public class WrapperExercise01 {
    public static void main(String[] args) {
        Integer i11 = 127;
        int i12 = 127;
        System.out.println(i11 == i12);

        Integer i21 = 128;
        int i22 = 128;
        System.out.println(i21 == i22);
        
        // 由上文,我们可以看出,只要有基本数据类型;
        // 判断的就是值是否相等。
    }
}

==只要有基本数据类型, 号 判断的就是值是否相等。


String类:

String类的理解和创建对象:

  1. String 对象用于保存字符串,也就是一组字符序列;

  2. 字符串常量对象是用双引号括起来的字符序列。例如:“你好”、“Hello”等;

  3. 字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节;

  4. String 类常用的构造器有很多(其余看手册):

  5. String s1 = new String();

  6. String s2 = new String(String original);

  7. String s3 = new String(char[] a);

  8. String s4 = new String(char[] a, startIndex, int count);

  9. String s5 = new String(byte[] b);

  10. String 实现了Serializable接口,说明 String 对象可以串行化(即可以在网络传输,可以存储在文件中);

  11. String 实现了Comparable接口,说明 String 对象可以进行比较大小;

  12. String 还是一个final类(不能被其他类继承);

  13. String 中有一个属性 private final char value[];用于存放字符串内容——一定要注意,value是一个final类型的,赋值后不可修改(不是说的数组内容不可以修改,而是指的是地址不能修改,为什么呢?因为value指向的是一个空间,修改空间内部的值不会对地址有影响)。

  14. 常量池中的常量拥有自己的地址。

package com.jiangxian.string_;

public class String01 {
    public static void main(String[] args) {
        final char[] value = {'a','b','c'};
        value[0] = 'A';
        char[] a = {'a'};
        // value = a; 改变地址会报错
    }
}

创建String 对象的两种方式:

  1. 方式一:直接赋值——String s = “JiangXian”;
    1. 先从常量池查看是否有“JiangXian”数据空间,若有,将 s 直接指向该数据空间;
    2. 若没有,在数据空间中创建“JiangXian”数据空间,再将 s 指向该空间;
    3. s 最终指向的是常量池的地址空间。
  2. 方式二:调用构造器——String s = new String(“JiangXian”);
    1. 先在堆中创建空间(创建String对象),里面维护了 value 属性,value 指向常量池的“JiangXian”空间;
    2. 若常量池中没有“JiangXian”,那么便在常量池中创建,然后通过 value 指向常量池中的“JiangXian”
    3. 最终指向的是堆中的地址空间。

String的特性:

  1. String 是一个 final 类,不可以被继承;

  2. String 代表不可变的字符序列——不可变性;

  3. 字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的。

    String s1 = "Hello";
    s1 = "haha";
    

上述这个代码我们来分析一下,首先我们创建了一个字符串常量对象“Hello”,这个对象是存储在常量池中的,然后我们将s1 重新赋值为“haha”。

  1. 要注意的是,我们并不是将原来的字符串常量对象“Hello”的内容改变了,我们没有对这个对象进行任何改变!字符串一旦被定义就是不可便的。
  2. 我们是先在常量池中创建了另一个为“haha”的字符串常量对象,然后将原来 s1 指向“Hello”断开,再让 s1 指向 “haha”即可。
  3. 所以我们创建了两个字符串常量对象,而不是创建了一个字符串常量并对其内容进行修改。

字符串常量拼接:

String a = "hello" + "abc";

这段代码仅仅创建了一个字符串常量对象“helloabc”而不是三个对象“hello”,”abc”,”helloabc”。

分析:

  1. 编译器会帮我们进行一个优化,判断创建的常量池对象,是否有引用指向(是否有变量指向它);
  2. 在底层上就会被优化为:String a = “helloabc”;

字符串变量拼接:

String a = "hello"; //创建了一个字符串常量对象。
String b = "abc"; //创建了一个字符串常量对象。
String c = a + b; // 这个语句是怎么运行的呢?

底层执行步骤:

  1. 先创建一个StringBuilder对象,命名为sb;
  2. 调用 sb.append(a);
  3. 调用 sb.append(b);
  4. 最后 String c = sb.toString;

所以最后 c 指向的是堆中的一个String 对象,内部的 value 属性指向常量池中新创建的“helloabc”。

所以一共创建了三个字符串常量对象。

拼接小结:

  1. 常量相加,看常量池,底层会进行优化;
  2. 变量相加,是在堆中。
package com.jiangxian.string_;

public class StringExercise08 {
    public static void main(String[] args) {
        String a = "hello"; //创建了一个字符串常量对象。
        String b = "abc"; //创建了一个字符串常量对象。
        String c = a + b; // 这个语句是怎么运行的呢?
        System.out.println(c == c.intern()); // 这里为true让我有些困惑
        String hello = new String("hello");
        System.out.println(hello == hello.intern());
    }
}

对String是不变的字符串的加深理解:

package com.jiangxian.string_;

public class StringExercis10 {
    String str = new String("jiangxian");
    final char[] ch = {'j','a','v','a'};
    public void change(String str, char ch[]){
        str = "java"; // 一个局部变量
        /*
            1、java中只有值传递,对基本数据类型传递的是值,对引用类型传递的是对象的引用(内存地址的副本);
            2、那么我得到困惑点就来了,为什么String是非基本数据类型,且是引用数据类型,为什么我们对它的修改没有作用呢?
            3、那是因为在java中,String是一个不可变的:
                任何对String的修改操作都会导致创建一个新的String对象。
            4、属性的str 指向了一个 "jiangxian"对象的引用;
            5、当其作为参数传递给change方法时,传递的是属性的str的引用,即指向“jiangxian”对象的内存地址;
            6、局部变量str只是创建了一个新的对象"java",其对于原来的属性的str没有任何影响。
            7、因此当change方法结束后,原来的属性的str仍然指向"jiangxian"
         */
        ch[0] = 'h';
        /*
            那这边为什么能修改呢?
            因为其修改的是内存地址中存放的值。
         */
    }

    public static void main(String[] args) {
        StringExercis10 s = new StringExercis10();
        s.change(s.str,s.ch);
        System.out.print(s.str + " and ");
        System.out.println(s.ch);
    }
}

为了方便理解,我又写了一段代码,希望对各位的理解有所帮助:

package com.jiangxian.string_;

public class test {
    public char[] c1= {'j','a','v','a'};
    public void change(char[] c){
        char[] c2 = {'h','l','l','o'};
        c = c2;
    }
    public static void main(String[] args) {
        test test = new test();
        test.change(test.c1);
        System.out.println(test.c1);
    }
}

String类的常见方法:

说明:

String 类是保存字符串常量的。每次更新都需要重新开辟空间,效率极低,因此java设计者还提供了StringBuilderStringBuffer 来增强String 的功能,并提高效率。

常见方法概述:

  • equals——区分大小写,判断内容是否相等;
  • equalsIgnoreCase——忽略大小写的判断内容是否相等;
  • length——获取字符的个数,字符串的长度;
  • indexOf——获取字符在字符串中第一次出现的索引,索引从0开始,若找不到,返回-1;
  • lastIndexOf——获取字符在字符串中最后出现的索引,索引从0开始,若找不到,返回-1;
  • substring——截取指定范围的字串;
  • trim——去前后空格;
  • charAt——获取某索引位置的字符,注意,想要获取某索引位置的字符不能使用Str[index]格式。
  • toUpperCase——转换为大写形式;
  • toLowerCase——转换为小写形式;
  • concat——拼接字符串;
  • replace——替换字符串中的字符;
  • split——分割字符串,对于某些分割字符,我们需要转移字符;
  • compareTo——比较两个字符串的大小;
  • toCharArray——转换成字符数组;
  • format——格式化字符串,%s 字符串,%c 字符, %d 整型, %.2f 浮点型
package com.jiangxian.string_;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class StringMethod {
    public static void main(String[] args) {
        // 1.equals: 比较内容是否相等,区分大小写。
        String str1 = "JiangXian";
        System.out.println("hello".equals(str1));

        // 2.equalsIgnoreCase: 忽略大小写的判断是否相等。
        String username = "johN";
        System.out.println("john".equalsIgnoreCase(username));

        // 3.length: 获取字符的个数,即字符串的长度。
        System.out.println("Jiangxian".length());

        // 4.indexOf: 获取字符串对象中第一次出现的索引,索引从0开始,若找不到,返回0.
        System.out.println(str1.indexOf('X'));
        String s1 = "wer@terwe@g";
        System.out.println("第一个 we 的 index为:" + s1.indexOf("we")); // 若找的是一个字符串,返回的是符合该字符串的第一个字符所在位置的索引

        // 5.lastIndexOf: 获取字符在字符串中最后一次出现的索引,索引从0开始,若找不到,返回0.
        System.out.println("最后一个 we 的 index 为:" + s1.lastIndexOf("we"));

        // 6.substring: 截取指定范围的字串。
        String name = "Hello,JiangXian";
        System.out.println(name.substring(6)); // 从索引6开始(包括),截取后面所有的内容
        System.out.println(name.substring(0,5));// 从0开始,截取到5前,即左闭右开[0,5)。

        // 7.trim: 去掉前后的空格。
        System.out.println(" m ".trim());

        // 8.charAt: 获取字符串中指定位置的字符。
        System.out.println("Hello".charAt(2));

        // 9.toUpperCase: 转换成大写。
        System.out.println("hello".toUpperCase());

        // 10.toLowerCase: 转换成小写。
        System.out.println("HELLO".toLowerCase());

        // 11.concat: 拼接字符串
        String s2 = "宝玉";
        s2 = s2.concat("林黛玉").concat("薛宝钗");
        System.out.println(s2);

        // 12.replace: 替换字符串中的字符。
        s2 = "宝玉 and 黛玉 黛玉 黛玉";
        String s12 = s2.replace("黛玉","宝钗");
        System.out.println("s2: " + s2);
        System.out.println("s12: " + s12);

        // 13.split: 分割字符串,对于某些分割字符,我们需要转义字符。
        String s3 = "E:\\self_study\\NoteBook\\Java";
        String[] splits = s3.split("\\\\");
        System.out.println("====分割后的字符串====");
        for(String split:splits){
            System.out.println(split);
        }

        // 14.toCharArray: 转换成字符数组。
        String s = "hello";
        char[] c = s.toCharArray();
        for(char cc:c){
            System.out.println(cc);
        }

        // 15.compareTo: 比较两个字符串的大小,
        // 若前者大,则返回正数,
        // 后者大,则返回负数,
        // 若相等,返回0
        /*
                public int compareTo(String anotherString) {
                    int len1 = value.length;
                    int len2 = anotherString.value.length;
                    int lim = Math.min(len1, len2);
                    char v1[] = value;
                    char v2[] = anotherString.value;

                    int k = 0;
                    while (k < lim) {
                        char c1 = v1[k];
                        char c2 = v2[k];
                        if (c1 != c2) {
                            return c1 - c2;
                        }
                        k++;
                    }
                    return len1 - len2;
                }
         */
        String a = "jac";
        String b = "jack";
        String d = "jcck";
        System.out.println(a.compareTo(b));
        System.out.println(b.compareTo(d));

        // 16. format: 格式化,
        // %.2f——会自动进行四舍五入处理。
        String info = String.format("我的姓名%s 年龄是%d 成绩是%.2f 性别是%c。希望大家喜欢我!",
                "JiangXian", 21, 99.199, 'M');
        System.out.println("info: " + info);
        String formatStr = "我的姓名%s 年龄是%d 成绩是%.2f 性别是%c。希望大家喜欢我!";
        String info2 = String.format(formatStr, "JiangXian", 21, 99.199, 'M');
        System.out.println("info2: " + info2);
    }
}


StringBuffer类:

基本介绍:

  • java.lang.StringBuffer 代表可变的字符序列,可以对字符串内容进行增删;
  • 很多方法与 String 相同,但 StringBuffer是可变长度;
  • StringBuffer 是一个容器。
    • StringBuffer 是 final 类,是最终类,不能被继承;
    • 实现了 Serializable 接口,可以串行化,可以保存文件,或网络传输;
    • 继承了抽象类 AbstractStringBuilder;
    • AbstractStringBuilder 属性 char[] value,存放的字符序列。
package com.jiangxian.stringbuffer_;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class StringBuffer01 {
    public static void main(String[] args) {
        // 1.StringBuffer 的直接父类是 AbstractStringBuilder;
        // 2.StringBuffer 实现了 Serializable,即StringBuffer的对象可以串行化;
        // 3.在父类 AbstractStringBuilder 有属性 char[] value,
        //      其与String的属性value是不同的,其不是final,该 value 数组存放字符串内容,引出存放在堆中。
        // 4.StringBuffer 是一个 final 类,不能被继承;
        // 5.因为StringBuffer字符内容是存在 char[] value,所以在变化(增加/删除)
        //      不用每次都更换地址(即不是每次创建新对象),所以效率高于String
        StringBuffer stringBuffer = new StringBuffer("hello");
        System.out.println(stringBuffer);
    }
}

AbstractStringBuilder 的 char[] value不是final,所以存放在堆中。

String 和 StringBuffer 相互转换:

在开发过程中,我们通常需要将 String 和 StringBuffer 进行转换。

package com.jiangxian.stringbuffer_;

import java.nio.Buffer;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class StringAndStringBuffer {
    public static void main(String[] args) {
        // 看 String ——》StringBuffer:
        String str = "hello tom";
        // 方式1:使用构造器
        // 注意:返回的才是 StringBuffer 对象,对 str 本身没有影响。
        StringBuffer stringBuffer = new StringBuffer(str);
        // 方式2:使用append方法
        StringBuffer stringBuffer1 = new StringBuffer();
        stringBuffer1 = stringBuffer1.append(str);
        
        // StringBuffer ——》String:
        StringBuffer stringBuffer3 = new StringBuffer("JiangXian");
        // 方式1:使用 StringBuffer 提供的 toString 方法。
        String str1 = stringBuffer3.toString();
        // 方式2:使用构造器来搞定。
        String str2 = new String(stringBuffer3);
    }
}

StringBuffer类常见方法:

增删改查操作时我们常用的,其它方法和String类一样~

  • append——增;
  • delete——删;
  • replace——改;
  • insert——插入。
package com.jiangxian.stringbuffer_;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class StringBufferMethod {
    public static void main(String[] args) {
        StringBuffer s = new StringBuffer("hello");
        // 增:
        s.append(','); //hello,
        s.append("张三丰"); // hello,张三丰
        s.append("赵敏").append(100).append(true).append(10.5); // hello,张三丰赵敏100true10.5

        // 删:
        /*
            删除索引为 >= start && < end 处的字符;
            即左闭右开
         */
        s.delete(11,14); // 删除了100
        System.out.println(s);

        // 改:
        s.replace(9,11,"周芷若");
        System.out.println(s); // 使用周芷若,替换 索引9-11的字符[9,10]处的赵敏

        // 插:
        s.insert(9,"赵敏");
        System.out.println(s);
    }
}

练习:

Exercise01:

package com.jiangxian.stringbuffer_;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class StringBufferExercise01 {
    public static void main(String[] args) {
        String str = null;
        StringBuffer sb = new StringBuffer();
        sb.append(str);
        /*
        private AbstractStringBuilder appendNull() {
            int c = count;
            ensureCapacityInternal(c + 4);
            final char[] value = this.value;
            value[c++] = 'n';
            value[c++] = 'u';
            value[c++] = 'l';
            value[c++] = 'l';
            count = c;
            return this;
        }
         */
        System.out.println(sb.length());
        System.out.println(sb);

        // 但是不能这样写:
        // 为什么呢?
        /*
        public StringBuffer(String str) {
            super(str.length() + 16);
            append(str);
        }
         */
        // 我们发现,在接受String的构造器里,在调用父类的构造器时,需要str.length();
        // 所以String对象不能时空。
        StringBuffer sb1 = new StringBuffer(str);
        System.out.println(sb1);
    }
}

Exercise02:

输入商品名称和商品价格,要求打印效果实例为:商品名 商品价格,要求:价格的小数点前面每三位用逗号隔开,再输出。

package com.jiangxian.stringbuffer_;
import java.util.Scanner;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class StringBufferExercise02 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("======请输入商品名称=====");
        String name = scanner.next();
        StringBuffer sb = new StringBuffer();
        System.out.println("=====请输入商品价格=====");
        sb.append(scanner.next());

        int pointIndex = sb.indexOf(".");
        for (int i = pointIndex - 3; i > 0; i-=3) {
            sb.insert(i,',');
        }
        System.out.println("=====修改后的结果=====");
        System.out.println(name + "  " + sb);
    }
}


StringBuilder类:

基本介绍:

  1. 一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步(即不保证线程安全)。此类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候。若可能,建议先使用该类,因为再大多实现中,比 StringBuffer 快;
  2. 在 StringBuilder 上的主要操作时 appendinsert 方法,可重载这些方法,以接受任意类型的数据;
  3. StringBuilder 是final;
  4. 继承了 AbstractStringBuilder,属性 char[] value,内容存到 value——即存放在堆内;
  5. 实现了 Serializable 接口,可以串行化,可网络传输与保存到文件。

StringBuilder常用方法:

StringBuilder 和 StringBuffer 均代表可变的字符序列,方法是一样的,所以使用和 StringBuffer 一样。

package com.jiangxian.stringbuilder_;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class StringBuilder01 {
    public static void main(String[] args) {
        // 1.StringBuilder 继承了 AbstractStringBuilder 类;
        // 2.实现了 Serializable 接口,说明 StringBuilder 对象是可以串行化
        //  (对象可以网络传输,保存在文件中);
        // 3.StringBuilder 对象字符仍然是存放在其父类 AbstractStringBuilder 的 char[] value;
        //   因此,字符序列存放在堆中;
        // 4.StringBuilder 是 final 类,不能被继承;
        // 5.StringBuilder 的方法,没有做互斥的处理,即没有 synchronized 关键字,
        //      因此在单线程的情况下使用 StringBuilder。
        StringBuilder stringBuilder = new StringBuilder();
    }
}

String、StringBuffer和StringBuilder的比较:

  1. StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且方法也一样;
  2. String:不可变字符序列,效率低,但是复用率高(字符串常量存放在常量池中,有多个对象指向);
  3. StringBuffer:可变字符序列,效率较高(增删改查),线程安全,看源码;
  4. StringBuilder:可变字符序列,效率最高,但是线程不安全(没有synchronized修饰);
  5. String 使用注意事项说明:
    1. String s = “a”; //创建了一个字符串
    2. s += “b”; // 实际上原来常量池中的"a"字符串对象已经丢弃了,现在又产生了一个新的字符串对象"ab"。现在s指向常量池中的"ab"字符串对象。若多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。若这样的操作放到循环中,会极大影响程序的性能。
  6. 由上文得,若要对字符序列大量修改,不要用String。

String、StringBuffer和StringBuilder的选择:

使用的原则:

  1. 若字符串存在大量的修改操作,一般使用StringBuffer 或 StringBuilder;
  2. 若字符串存在大量的修改操作,且是单线程,使用StringBuilder;
  3. 若字符串存在大量的修改操作,且是多线程,使用StringBuffer;
  4. 若我们的字符串很少修改,被多个对象引用,使用String,比如配置信息等。

Math:

基本介绍:

Math 类包含用于执行基本数学运算的,如初等指数、对数、平方根和三角函数。

方法(均为静态方法):

  • abs——返回绝对值;
  • acos——返回一个值的反余弦值,返回的角度在 0.0 到 pi 之间;
  • asin——返回一个值的反正弦值,返回的角度在 -pi/2 到 pi/2 之间;
  • atan——返回一个值的反正切值,返回的角度在 -pi/2 到 pi/2 之间;
  • atan2(double y, double x)——将矩形坐标(x,y)转换成极坐标(r, theta),返回所得角 theta;
  • cbrt——返回 double 值的立方根。
package com.jiangxian.math_;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class MathMethod_ {
    public static void main(String[] args) {
        // 1.abs 绝对值:
        int abs = Math.abs(-9);
        System.out.println(abs);

        // 2.pow 求幂:
        double pow = Math.pow(2, 4);
        System.out.println(pow);

        // 3.ceil 向上取整,返回 >= 该参数的最小整数(转成double):
        double ceil = Math.ceil(3.9);
        System.out.println(ceil);

        // 4.floor 向下取整,返回 <= 该参数的最小整数(转成double):
        double floor = Math.floor(-4.1);
        System.out.println(floor);
        double floor1 = Math.floor(3.9);
        System.out.println(floor1);

        // 5.round 四舍五入,
        long round = Math.round(5.51);
        System.out.println(round);

        // 6.sqrt 开方:
        double sqrt = Math.sqrt(9);
        System.out.println(sqrt);

        // 7.random 求随机数:
        // 返回的是 0 <= x < 1之间的一个随机小数
        // 那我们要怎么创建一个a~b之间的随机整数呢?
        // (int)(a + Math.random() * (b-a+1))
        // 这样就得到了 a<=x<=b
        System.out.println("====100个2~7的随机整数====");
        for (int i = 0; i < 100; i++) {
            System.out.println((int)(2 + Math.random()*(6)));
        }

        // 8.max 最大值:
        int max = Math.max(1, 2);
        System.out.println("max" + max);

        // 9.min 最小值:
        int min = Math.min(1, 2);
        System.out.println("min" + min);
    }
}


Arrays类:

常见方法:

Arrays 里面包含了一系列的静态方法,用于管理和操作数组(比如排序和搜索).

  1. toString——返回数组的字符串形式;
  2. sort——排序(自然排序和定制排序);
  3. binarySearch——通过二分搜索法进行搜查,要求必须排好序;
  4. copyOf——数组元素的复制;
  5. fill——数组元素的填充;
  6. equals——比较两个数组元素内容是否一致。
package com.jiangxian.arrays_;
import java.util.Arrays;
import java.util.Comparator;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class ArraysMethod {
    public static void main(String[] args) {
        Integer[] integers = {1, 20 , 90};
        // 遍历数组:
        // for(int i = 0; i < integers.length; i++){
        //     System.out.println(integers[i]);
        // }

        // 直接使用toString 方法,显示数组:
        System.out.println(Arrays.toString(integers));

        // 演示 sort方法的使用:
        Integer[] arr = {1, -1, 7, 0, 89};
        // Arrays.sort(arr); // 默认排序方法。

        // 定制排序:
        Arrays.sort(arr,new Comparator(){
            @Override
            public int compare(Object o1, Object o2) {
                Integer i1 = (Integer)o1;
                Integer i2 = (Integer)o2;
                return i2 - i1;
            }
        });
        // 分析源码:
        // 1.Arrays.sort(arr, new Comparator(){})
        // 2.最终到 TimSort类的
        //      private static <T> void binarySort(T[] a, int lo, int hi, int start,
        //                      Comparator<?super T>c)()
        // 3.执行到 binarySort 方法的代码,会根据动态绑定机制 c.compare()执行我们传入的
        //      匿名内部类的 compare()
//        while (left < right) {
//            int mid = (left + right) >>> 1;
//            if (c.compare(pivot, a[mid]) < 0)
//                right = mid;
//            else
//                left = mid + 1;
//        }
        // 4.可以看到我们创建的Comparator会因为我们返回值的正负来决定排序的顺序
        //      这体现了 接口编程+动态绑定+匿名内部类的综合使用
        //      在下面的学习底层框架和源码的使用方法,会非常常见。
        System.out.println(Arrays.toString(arr));
    }
}

对定制排序的进一步解读:

package com.jiangxian.arrays_;

import com.jiangxian.wrapper_.integer_.Integer01;

import java.util.Arrays;
import java.util.Comparator;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class ArraysSortCustom {
    public static void main(String[] args) {
        int[] arr = {1, -1, 8, 0, 20};
        bubble02(arr, new Comparator(){
            @Override
            public int compare(Object o1, Object o2) {
                Integer i1 = (Integer)o1;
                Integer i2 = (Integer)o2;
                return i1 - i2;
            }
        });
        System.out.println(Arrays.toString(arr));
    }

    // 使用冒泡排序:
    public static void bubble01(int[] arr){
        int tmp = 0;
        for(int i = 0; i < arr.length - 1; i++){
            for(int j = 0; j < arr.length -1 - i; j++){
                if(arr[j] > arr[j+1]){
                    tmp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = tmp;
                }
            }
        }
    }

    // 冒泡结合定制:
    public static void bubble02(int[] arr, Comparator c){
        int tmp = 0;
        for(int i = 0; i < arr.length - 1; i++){
            for(int j = 0; j < arr.length -1 - i; j++){
                // if(arr[j] > arr[j+1]){}
                // 数组排序由c.compare(arr[j], arr[j+1])的返回值决定
                if(c.compare(arr[j], arr[j+1]) > 0){
                    // (1)若返回的是 i1 - i2;
                    //      当前一个元素比后一个元素大时,返回的是>0;
                    //      所以执行交换,最后的结果为从小到大的排序。
                    // (2)若返回的是 i2 - i1;
                    //      当后一个元素比前一个元素大时,返回的是>0;
                    //      所以执行交换,最后的结果为从大到小的排序。
                    tmp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = tmp;
                }
            }
        }
    }
}

package com.jiangxian.arrays_;

import java.util.Arrays;
import java.util.List;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class ArraysMethod02 {
    public static void main(String[] args) {
        Integer[] arr = {1, 2, 90, 123, 567};
        // 1.binarySearch 通过二分搜索法进行查找,要求必须排序好
        // 为什么呢?
        // 这种搜索就是将要查找的值,与数组中间的数比较,以此缩减长度
        // 所以其必须是有序的
        // 若数组中不存在该元素,就返回 -(low+1)
        // 就是这个元素要是存在应该在的位置。
        int index = Arrays.binarySearch(arr,567);
        int notFound = Arrays.binarySearch(arr,91);
        System.out.println("567's index: " + index);
        System.out.println("91's index: " + notFound);

        // 2.copyOf 数组元素复制:
        /*
            1.从 arr 数组中,拷贝 arr.length 个元素到 newArr数组中;
            2.若拷贝的长度 > arr.length 就在新数组的后面,增加 null;
            3.若拷贝长度 < 0 就抛出异常 NegativeArraySizeException
            4.该方法的底层使用的是System.arraycopy()
         */
        Integer[] newArr = Arrays.copyOf(arr, arr.length);
        System.out.println(Arrays.toString(newArr));

        // 3.fill 数组元素的填充:
        Integer[] num = new Integer[]{9,3,2};
        Arrays.fill(num, 99);
        System.out.println("==num 数组填充后==");
        System.out.println(Arrays.toString(num));

        // 4.equals 比较两个数组元素内容是否完全一致
        Integer[] arr2 = {1, 2, 90, 123};
        // (1)若arr和arr2数组的元素一样,则方法true;
        // (2)若不是完全一样,就返回false。
        boolean equals = Arrays.equals(arr,arr2);
        System.out.println("equals" + equals);

        // 5.asList 将一组值,转换成List
        // (1) asList 方法,会将(2,3,4,5,6,1)数据转成一个List集合
        // (2) 返回 asList 编译类型 List(接口)
        // (3) asList 运行类型 java.util.Arrays$ArrayList, 是Arrays类的
        List asList = Arrays.asList(2,3,4,5,6,1);
        System.out.println("asList:" + asList);
        System.out.println("asList的运行类型" + asList.getClass());
    }
}

Arrays练习:

自定义Book类,里面包含name 和 price,按price 排序(从大到小)。要求使用两种方法排序(默认和定制)排序,有一个 Book[] books = 4本书对象。

默认排序我懒得写了,只写了定制。

package com.jiangxian.arrays_;

import java.util.Arrays;
import java.util.Comparator;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class ArraysExercise {
    public static void main(String[] args) {
        Book[] books = new Book[4];
        books[0] = new Book("红楼梦", 100);
        books[1] = new Book("金瓶梅新", 90);
        books[2] = new Book("青年文摘20年", 20);
        books[3] = new Book("java从入门到放弃~", 300);
        Arrays.sort(books, new Comparator(){
            @Override
            public int compare(Object o1, Object o2) {
                Book b1 = (Book) o1;
                Book b2 = (Book) o2;
                double difference = b1.getPrice() - b2.getPrice();
                // 价格从小到大
                if (difference > 0){
                    return 1;
                }else if (difference <0){
                    return -1;
                }else{
                    return 0;
                }
            }
        });
        System.out.println("=====按价格从小到大排序:=====");
        System.out.println(Arrays.toString(books));

        Arrays.sort(books, new Comparator(){
           @Override
           public int compare(Object o1, Object o2) {
               Book b1 = (Book) o1;
               Book b2 = (Book) o2;
               double difference = b2.getPrice() - b1.getPrice();
               if (difference > 0){
                   return 1;
               }else if (difference <0){
                   return -1;
               }else{
                   return 0;
               }
           }
        });
        System.out.println("=====按价格从大到小排序:=====");
        System.out.println(Arrays.toString(books));

        Arrays.sort(books, new Comparator(){
            @Override
            public int compare(Object o1, Object o2) {
                Book b1 = (Book) o1;
                Book b2 = (Book) o2;
                return b2.getTitle().length() - b1.getTitle().length();
            }
        });
        System.out.println("=====按照书名长度排序=====");
        System.out.println(Arrays.toString(books));
    }
}

class Book{
    private String title;
    private double price;
    public Book(String title, double price) {
        this.title = title;
        this.price = price;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book{" +
                "title='" + title + '\'' +
                ", price=" + price +
                '}';
    }
}


System类:

常见方法:

  • exit——退出当前程序;
  • arraycopy——复制数组元素,比较适合底层调用,一般使用 Arrays.copyOf 完成复制数组;
  • currentTimeMillens——返回当前时间距离1970-1-1的毫秒数;
  • gc——垃圾回收机制。
package com.jiangxian.system;

import java.util.Arrays;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class System_ {
    public static void main(String[] args) {
        // 1.exit 退出当前程序。
        // System.out.println("Hello.");
        // System.exit(0);// 0表示一个状态,正常的状态
        // System.out.println("World.");

        // 2.arraycopy 复制数组元素,比较适合底层调用,
        // 一般使用 Arrays.copyOf完成复制数组
        int[] src = {1, 2, 3};
        int[] dest = new int[3]; // dest 当前是 {0, 0, 0}
        System.arraycopy(src, 1, dest, 1, 2);
        /*
            src – the source array.
            srcPos – starting position in the source array.
            dest – the destination array.
            destPos – starting position in the destination data.
            length – the number of array elements to be copied.
         */
        System.out.println("dest=" + Arrays.toString(dest));

        // 3.currentTimeMillens 返回当前时间距离 1970-1-1的毫秒数
        System.out.println(System.currentTimeMillis());
    }
}


BigInteger 和 BigDecimal类:

BigInteger 和 BigDecimal 介绍:

应用场景:

  1. BigInteger 适合保存比较大的整型;
  2. BigDecimal 适合保存精度更高的浮点型(小数)。

常见方法:

  • add 加;
  • subtract 减;
  • multiply 乘;
  • divide 除。
package com.jiangxian.bignum_;

import java.math.BigDecimal;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class BigDecimal_ {
    public static void main(String[] args) {
        // 当我们保存一个浮点数时,double的精度可能不够用;
        // double d = 1999.111111111111111111111111111111111111111111111111111;
        BigDecimal bigDecimal = new BigDecimal("1999.111111111111111111111111111");
        BigDecimal bigDecimal2 = new BigDecimal("3");
        System.out.println(bigDecimal);

        // 若对BigDecimal进行运算,和BigInteger类似
        // 不同的是,在BigDecimal的除法中可能出现无限小数。
        // 所以我们在进行除法的时候,指定精度即可,BigDecimal.ROUND_CEILING
        // 这样若有无限小数,只会保留分子的精度。
        System.out.println(bigDecimal.divide(bigDecimal2,BigDecimal.ROUND_CEILING));
    }
}


日期类:

我觉得这边没有什么需要刻意去记得,需要用的时候去查询即可。所以写的比较简略。

第一代日期类Date:

  1. Date:精确到毫秒,代表特定的时间;
  2. SimpleDateFormat:格式和解析日期的类——其允许进行格式化(日期->文本)、解析(文本->日期)和规范化。
    1. 语法(仅是常用的):SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
    2. String format = sdf.format(d1);// 将日期转换成指定格式的字符串
    3. Date parse = sdf.parse(format);// 将字符串转换为Date

第二代日期类Calendar:

public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>

Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间提供了一些转换方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。

  1. Calendar 是一个抽象类,且构造器是private的;
  2. 可以通过 getInstance() 来获取实例;
  3. 提供大量的方法和字段提供给程序员;
  4. Calendar 没有提供对应的格式化的类,因此需要程序员自己组合来输出;
  5. 若我们需要按照24小时进制来获取时间,Calendar.Hour;——》Calendar.HOUR_OF_DAY;

第三代日期类:

前两代的不足:

  1. Date——在jdk1.0就已经存在,太多的方法已经被弃用;
  2. Calendar:
    1. 可变性:像日期和时间这样的类应该是不可变的;
    2. 偏移性:Date中的年份是从1900开始的,而月份都从0开始,和实际不符;
    3. 格式化:格式化只对Date有用,Calendar没有格式化;
    4. 线程不安全;
    5. 不能处理闰秒。

介绍:

  1. LocalDate(日期/年月日),可以获取日期字段;
  2. LocalTime(时间/时分秒),可以获取时间字段;
  3. LocalDateTime(日期时间/年月日时分秒),可以获取日期和时间字段。
  4. 是在JDK8才加入的。

DateTimeFormatter 格式日期类:

DateTimeFormat dtf = DateTimeFormatter.ofPattern(格式);
String str = dtf.format(日期对象);

Instant时间戳:

类似于Date,提供了一系列和Date类转换的方式。

  • Instant——》Date:
    • Date date = Date.from(Instant);
  • Date——》Instant:
    • Instant instant = date.toInstant();
      我觉得这边没有什么需要刻意去记得,需要用的时候去查询即可。所以写的比较简略。

第一代日期类Date:

  1. Date:精确到毫秒,代表特定的时间;
  2. SimpleDateFormat:格式和解析日期的类——其允许进行格式化(日期->文本)、解析(文本->日期)和规范化。
    1. 语法(仅是常用的):SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
    2. String format = sdf.format(d1);// 将日期转换成指定格式的字符串
    3. Date parse = sdf.parse(format);// 将字符串转换为Date

第二代日期类Calendar:

public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>

Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间提供了一些转换方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。

  1. Calendar 是一个抽象类,且构造器是private的;
  2. 可以通过 getInstance() 来获取实例;
  3. 提供大量的方法和字段提供给程序员;
  4. Calendar 没有提供对应的格式化的类,因此需要程序员自己组合来输出;
  5. 若我们需要按照24小时进制来获取时间,Calendar.Hour;——》Calendar.HOUR_OF_DAY;

第三代日期类:

前两代的不足:

  1. Date——在jdk1.0就已经存在,太多的方法已经被弃用;
  2. Calendar:
    1. 可变性:像日期和时间这样的类应该是不可变的;
    2. 偏移性:Date中的年份是从1900开始的,而月份都从0开始,和实际不符;
    3. 格式化:格式化只对Date有用,Calendar没有格式化;
    4. 线程不安全;
    5. 不能处理闰秒。

介绍:

  1. LocalDate(日期/年月日),可以获取日期字段;
  2. LocalTime(时间/时分秒),可以获取时间字段;
  3. LocalDateTime(日期时间/年月日时分秒),可以获取日期和时间字段。
  4. 是在JDK8才加入的。

DateTimeFormatter 格式日期类:

DateTimeFormat dtf = DateTimeFormatter.ofPattern(格式);
String str = dtf.format(日期对象);

Instant时间戳:

类似于Date,提供了一系列和Date类转换的方式。

  • Instant——》Date:
    • Date date = Date.from(Instant);
  • Date——》Instant:
    • Instant instant = date.toInstant();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2247402.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

传输控制协议(TCP)和用户数据报协议(UDP)

一、传输控制协议&#xff08;TCP&#xff09; 传输控制协议&#xff08;Transmission Control Protocol&#xff0c;TCP&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;由 IETF 的 RFC 793 定义。 它通过三次握手建立连接&#xff0c;确保数…

C++初阶(十五)--STL--list 的深度解析与全面应用

文章目录 一、头文件与基本概念 二、构造函数和析构函数 1.构造函数 2.析构函数 三、元素访问 front back 四、迭代器相关函数 begin end rebegin&#xff08;反向迭代器&#xff09; rend&#xff08;反向迭代器&#xff09; 五、容量相关函数 empty size max…

企业数智化新纪元,安全体系保驾护航

随着云计算、大数据、人工智能等技术的不断发展成熟&#xff0c;企业数智化建设进入到了深水区&#xff0c;网络安全已经成为企业发展最重要的基石。企业如何更好地拥抱先进生产力、构建强大的安全体系、重塑企业核心竞争力&#xff0c;是每一位技术决策者需要认真思考和解决的…

学Linux的第九天--磁盘管理

目录 一、磁盘简介 &#xff08;一&#xff09;、认知磁盘 &#xff08;1&#xff09;结构 &#xff08;2&#xff09;物理设备的命名规则 &#xff08;二&#xff09;、磁盘分区方式 MBR分区 MBR分区类型 扩展 GPT格式 lsblk命令 使用fdisk管理分区 使用gdisk管理分…

QT实现拷贝复制文件操作 QT5.12.3环境 C++实现

案例需求&#xff1a;利用QT线程操作&#xff0c;实现拷贝复制文件操作 代码&#xff1a; myfile.h #ifndef MYFILE_H #define MYFILE_H#include <QObject> #include <QDebug> #include <QThread> #include <QFile> #include <QtWidgets> class…

IDEA 2024安装指南(含安装包以及使用说明 cannot collect jvm options 问题 四)

汉化 setting 中选择插件 完成 安装出现问题 1.可能是因为之前下载过的idea&#xff0c;找到连接中 文件&#xff0c;卸载即可。

Jenkins-Git Parameter 插件实现指定版本的发布和回滚

在上一篇文章的基础设置上进行 1. 机器准备 开发10.0.0.204gitlab10.0.0.201jenkins10.0.0.200web10.0.0.202 2. 开发主机 在开发机器上修改不同版本的前端页面&#xff0c;并打上标签 第一次修改 [rootdev wheel]#vim index.html [rootdev wheel]#git commit -am "1…

Ubuntu ESP32开发环境搭建

文章目录 ESP32开发环境搭建安装ESP-IDF搭建一个最小工程现象 ESP32开发环境搭建 最近有个小项目需要用到能够联网的mcu驱动&#xff0c;准备玩玩esp的芯片&#xff0c;记录下ESP32开发环境搭建的过程。 ESP-IDF 是乐鑫科技为其 ESP32 系列芯片提供的官方开发框架。这个框架主…

《剖析 Spring 原理:深入源码的旅程(二)》

六、Spring 的 Bean 注入与装配 Spring 的 Bean 注入与装配的方式有很多种&#xff0c;可以通过 xml、get set 方式、构造函数或者注解等。简单易用的方式就是使用 Spring 的注解&#xff0c;Spring 提供了大量的注解方式&#xff0c;如 Autowired、Qualifier 等。Spring 还支持…

Git的使用_仓库管理_CI/CD介绍

文章目录 一、Git的基础知识一-1、什么是GitLinux命令行的git的简易安装Git项目的组成Git的基本工作流程Git文件的三种状态 一-2、存储库远程存储库与本地存储库创建存储库git init命令的使用方法1. 初始化一个新的 Git 仓库2. 在指定目录初始化一个新的 Git 仓库3. 初始化一个…

Android 实现悬浮球的功能

Android 实现悬浮球的功能 在 Android 中&#xff0c;实现悬浮球可以通过以下方式实现&#xff0c;常见的方法是使用 WindowManager 创建一个悬浮窗口。以下是具体的实现步骤&#xff1a; 1. 配置权限 在 AndroidManifest.xml 中添加悬浮窗权限&#xff1a; <uses-permis…

C语言数据结构学习:循环队列

C语言 数据结构学习 汇总入口&#xff1a; C语言数据结构学习&#xff1a;[汇总] 1. 循环队列 队列的博客&#xff1a;C语言数据结构学习&#xff1a;队列 循环队列会预先定义最大队列空间&#xff0c;然后定义一个数组&#xff0c;通过队列头和队列尾指针分别指向开头和结尾&…

Java教程:SE进阶【十万字详解】(下)

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/cat…

37_U-Net网络详解

1.U-Net 网络概述 U-Net 是一种深度学习模型&#xff0c;广泛用于图像的语义分割任务。U-Net 网络的结构特别适合医学影像分割&#xff0c;尤其在少量训练数据的情况下表现优异。该网络由一个编码器-解码器架构组成&#xff0c;具有对称的“U”形结构&#xff0c;因此得名为 U…

mysql-分析MVCC原理

一、MVCC简介 MVCC是一种用来解决读写冲读的无锁并发控制&#xff0c;也就是为事务分配单增长的时间戳&#xff0c;为每个修改保存一个版本&#xff0c;版本与事务时间戳关联&#xff0c;读操作只读该事务开始前的数据库的快照&#xff0c;所以MVCC可以为数据库解决一些问题。…

【CSP CCF记录】201812-2第15次认证 小明放学

题目 样例1输入 30 3 30 8 0 10 1 5 0 11 2 2 0 6 0 3 3 10 0 3 样例1输出 30 3 30 8 0 10 1 5 0 11 2 2 0 6 0 3 3 10 0 3 思路 参考&#xff1a;CCF小白刷题之路---201812-2 小明放学&#xff08;C/C 100分&#xff09;_小明放学测试数据-CSDN博客 我们使用一个for循环计算…

Kafka 分区分配及再平衡策略深度解析与消费者事务和数据积压的简单介绍

Kafka&#xff1a;分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析&#xff1a;从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析&#xff1a…

计算机网络-VPN虚拟专用网络概述

前面我们学习了在企业内部的二层交换机网络、三层路由网络包括静态路由、OSPF、IS-IS、NAT等&#xff0c;现在开始学习下VPN&#xff08;Virtual Private Network&#xff0c;虚拟专用网络&#xff09;&#xff0c;其实VPN可能很多人听到第一反应就是梯子&#xff0c;但是其实这…

《第十部分》1.STM32之通信接口《精讲》之IIC通信---介绍

经过近一周的USART学习&#xff0c;我深刻体会到通信对单片机的重要性。它就像人类的手脚和大脑&#xff0c;只有掌握了通信技术&#xff0c;单片机才能与外界交互&#xff0c;展现出丰富多彩的功能&#xff0c;变得更加强大和实用。 单片机最基础的“语言”是二进制。可惜&am…

【蓝桥杯C/C++】深入解析I/O高效性能优化:std::ios::sync_with_stdio(false)

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 蓝桥杯C/C 文章目录 &#x1f4af;前言&#x1f4af;C 语言与 C 语言的输入输出对比1.1 C 语言的输入输出1.2 C 语言的输入输出 &#x1f4af; std::ios::sync_with_stdio(false) 的作用与意义2.1 什么是 std::ios::s…