【入坑Java第六天】

常用类

String类

  • String是引用数据类型,不属于基本数据类型,"hello world"不是基本类型,而是一个String对象。通过String源码中public final char[] value,这个value属性是一个char数组,所以字符串底层实际上是一个字符数组,通过final说明,字符串一旦被创建是不可变的。

  • 以下程序创建了几个String对象:

    public class Test{
        String s1 = "hello";
        String s2 = "hello";
        String s3 = new String("hello");
        String s4 = new String("hello");
    }

    双引号括起来的“hello”一定会在字符串常量池中创建并保存一个。一旦使用new关键字必然会在堆内存中开辟新的存储空间,以上程序new了两次。以上程序一共有三个对象,堆内存中两个,字符串常量池中一个(实际上三个对象都在堆内存中,因为Java8之后字符串常量池挪到了堆内存中)。

  • 字符串拼接:

    public class Test{
        String s1 = "hello";
        String s2 = "world";
        String s3 = s1 + s2;
        String s4 = "abc" + "def";
    }

    通过加号可以进行字符串的拼接,字符串一旦被创建不可变,以上程序一共6个对象都保存在字符串常量池中。

    接下来通过一个程序看看有多少对象:

    public class Test {
        public static void main(String[] args) {
            String s = "";
            for (int i=0;i<10000;i++){
                s += i;
            }
        }
    }

    如果加号两边都是字符串常量的话,可以使用加号进行拼接,因为它们会在编译阶段拼接。但如果加号两个有变量的话,必然会在底层new一共StringBuilder对象进行字符串的拼接,如果循环拼接的话,每次循环都会new一共StringBuilder对象,所以效率较低。通过上面程序的循环可以猜到nwe了一万个对象StringBuilder对象,效率较低。怎么解决呢?在for循环外面创建一个StringBuilder对象,在for循环中调用StringBuilder的append方法进行字符串的拼接,这样只创建了一共StringBuilder对象,效率较高。如果字符串需要进行频繁拼接,建议使用StringBuilder对象。

  • 字符串的比较

    public class Test{
        public static void main(String[] args) {
            String s1 = new String("hello");
            String s2 = new String("hello");
            System.out.println(s1 == s2);
        }
    }
    ​
    运行结果:
    false

    双等号判断的是内存的地址,以上程序new了两次,所以是两个不同的内存地址,所以双等号判断结果是false。

    在String类中有一共方法可以进行字符串的比较:equals()方法。

    public class Test{
        public static void main(String[] args) {
            String s1 = new String("hello");
            String s2 = new String("hello");
            System.out.println(s1.equals(s2));
        }
    }
    ​
    运行结果:
    true

    通过以上程序可以得出,进行字符串比较使用equals()方法,equals()方法底层实际上也是双等号比较地址,但String类进行了重写比较的是内容。

  • String的构造方法:

    String(String original);
    String(byte[] bytes); // 将byte数组转成字符串
    String(byte[] bytes , int offset , int length); // 将byte数组的一部分转成字符串
    String(char[] value); // 将char数组转成字符串
    String(char[] value , int offset , int length); // 将char数组的一部分转成字符串

    以下代码进行测试:

    public class Test {
        public static void main(String[] args) {
    ​
            // 1
            String s1 = "hello";
    ​
            // 2
            String s2 = new String("world");
    ​
            //3
            byte[] bytes = {97,98,99,100};
            String s3 = new String(bytes);
            String s4 = new String(bytes,0,2);
    ​
            // 4
            char[] chars = {'你','好','呀'};
            String s5 = new String(chars);
            String s6 = new String(chars,0,2);
    ​
            System.out.println(s1);
            System.out.println(s2);
            System.out.println(s3);
            System.out.println(s4);
            System.out.println(s5);
            System.out.println(s6);
        }
    }
    ​
    运行结果:
    hello
    world
    abcd
    ab
    你好呀
    你好  
  • String类的常用方法

    char charAt(int index); 
    // 返回指定索引index的字符
    ​
    int compareTo(String anotherString); 
    // 比较两个字符串大小,a.compareTo(b),结果0表示a和b相等,结果<0表示a<b,结果>0表示a>b
    ​
    String concat(String str);
    // 拼接字符串,参数只能是String类型,如果参数是null,会出现空指针异常
    ​
    boolean contains(CharSequence s);
    // 判断当前字符串是否包含某个字符串s
    ​
    boolean endsWith(String sufffix);
    // 判断当前字符串是否以某个字符串结尾
    ​
    boolean equals(Object anObject);
    // 判断两个字符串是否相等
    ​
    boolean equalslgnoreCase(String anotherString);
    // 判断两个字符串是否相等,忽略大小写
    ​
    byte[] getBytes();
    // 将字符串转成byte数组
    ​
    int indexOf(String str);
    // 获取str字符串在当前字符串中第一次出现的索引
    ​
    int indexOf(String str , int frimlndex);
    // 从下标frimlndex开始,获取str字符串在当前字符串中第一次出现的索引
    ​
    int lastlndexOf(String str);
    // 获取str在当前字符串中最后一次出现的索引
    ​
    int lastlndexOf(String str , int frimlndex);
    // 从下标frimlndex开始,获取str在当前字符串中最后一次出现的索引
    ​
    String intern();
    // 从字符串常量池中获取当前字符串对象,获取则返回,如果获取不到,则新建一共字符串常量存储常量池中,并返回此字符串的引用
    ​
    int length();
    // 获取字符串的长度
    ​
    String replaceAll(String str,String newStr);
    // 将字符串str替换成newStr
    ​
    String[] split(String regex);
    // 将当前字符串对象是否以某个特定的符号进行拆分,返回String数组
    ​
    boolean startsWith(String prefix);
    // 判断当前字符串对象是否以某个子字符串开头
    ​
    String substring(int beginlndex);
    // 从beginlndex下标开始截取字符串,返回截取后的子字符串
    ​
    String substring(int beginlndex , itn endlndex);
    // 从beginlndex下标开始,到endlndex结束(不包括),截取字符串
    ​
    char[] toCharArray();
    // 将字符串转成char数组
    ​
    String toLowerCase();
    // 转成小写
    ​
    String toUpperCase();
    // 转成大写
    ​
    String trim();
    // 去除字符串前后空白
    ​
    String strip();
    // 去除字符串前后空白,并且支持unicode编码的空白
    ​
    static String valueOf(任意类型的参数);
    // 将任意类型的参数转成字符串

StringBuilder与StringBuffer

  • StringBuilder和StringBuffer是对String的一个补充,String称为不可变长字符串,而StringBuilder和StringBuffer称为可边长字符串,它们的区别是:StringBuffer在多线程并发的环境下,它是安全的。而StringBuilder是非线程安全的。其他方面基本相同。

  • StringBuilder主要是进行字符串的拼接,因为String做字符串的拼接使用+号,会在字符串常量池中生成多个String对象,效率较低,而StringBuilder不会。

  • 通过源码解析,StringBuilder底层是一个char[]数组,StringBuilder的默认初始化容量是16,通过构造方法也可以指定初始容量,StringBuilder和StringBuffer称为可边长字符串,那他们是怎么扩容的呢?扩容规则:原数组容量*2+2。

  • 在StringBuilder和StringBuffer中都有一个拼接字符串的方法,append()方法,通过以下程序进行测试:

    public class Test {
        public static void main(String[] args) {
    ​
            // 创建一个指定初始化容量的StringBuilder对象
            StringBuilder s = new StringBuilder(30);
    ​
            // 拼接(追加)字符串
            s.append("public class Test{\n");
            s.append("int a = 10");
            s.append("\n}");
    ​
            System.out.println(s);
    ​
        }
    }
    ​
    运行结果:
    public class Test{
    int a = 10
    }

包装类

  • Java语言中提供了8中基本类型,为了编程方便,对这8中基本类型又分别提供了它们的包装类。

  • 基本数据类型包装类型(java.lang包下)
    byteByte
    shortShort
    intInteger
    longLong
    floatFloat
    doubleDouble
    booleanBoolean
    charCharacter
  • 其中Byte,Short,Integer,Long,Float,Double它们6个的父类是Number,而Boolean和Charcater它们两个的父类是Object。

  • 以下程序测试包装类的拆箱和装箱:

    public class Test {
        public static void main(String[] args) {
    ​
            // 手动装箱,Integer提供了两个构造方法,可传入数字和字符串(这个字符串必须是一个数字)
            Integer x1 = Integer.valueOf(100);
            Integer x2 = Integer.valueOf("200");
            // 手动拆箱
             int y1 = x1.intValue();
             int y2 = x2.intValue();
            
            // 自动装箱
            Integer a = 500;
            // 自动拆箱
            int b = a;
    ​
        }
    }
  • 这里有一个经典的题,大家可以猜测一下结果是什么:

    public class Test {
        public static void main(String[] args) {
    ​
            Integer x = 127;
            Integer y = 127;
            System.out.println( x == y);
    ​
            Integer a = 128;
            Integer b = 128;
            System.out.println(a == b);
    ​
        }
    }
    ​
    运行结果:
    true
    false

    第一个结果是true,第二结果是false,这是为什么呢?

    因为在Integer类中有一个特殊的机制,在Integer类进行加载之后,会在堆(Java7之前在方法区)中生成一个整数常量池,这个常量池的范围-128~127,

    也就是说当数字没有超过这个范围的时候,会直接从整数常量池中拿这个Integer对象,如果超出了这个范围才会new对象。x和y没有超出这个范围,它们拿的是同一个对象,而a和b超出了这个范围,它们是new的对象,双等号判断的是内存地址,所以a和b是false。

日期类

  • 日期在实际的开发中应用非常广泛,主要涉及到的类有:java.utilDate , java,text,SimpleDateFormat , java.util.Calendar。

  • 如何获取系统当前时间:

    public class Test {
        public static void main(String[] args) {
    ​
            // 获取系统当前时间
            Date date = new Date();
    ​
            // 这里输出date会自动调用toString方法
            System.out.println(date);
    ​
        }
    }
    ​
    运行结果:
    Wed Aug 17 10:13:41 CST 2022
  • 通过以上的程序输出当前系统时间,但这个时间格式对于我们来说不太习惯,接下来将日期格式化:

    public class Test {
        public static void main(String[] args) {
    ​
            // 获取系统当前时间
            Date date = new Date();
    ​
            /*
                创建格式化日期对象
                y 年
                M 月
                d 日
                H 时
                m 分
                s 秒
                S 毫秒
            */
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss SSS");
            
            // 调用format方法进行格式化,返回一个字符串
            String time = sdf.format(date);
            
            System.out.println(time);
    ​
        }
    }
    ​
    运行结果:
    2022/08/17 10:17:31 238
  • 以上代码将日期类型转成String类型,怎么将String类型转成日期类型呢?

    public class Test {
        public static void main(String[] args) {
    ​
            // 创建一个格式化对象
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    ​
            // 创建一个字符串日期,这个字符串日期格式必须和日期格式化对象格式匹配
            String date = "2008/1/1 19:30:00";
    ​
            try {
                // 将String类型转成Date类型,使用parse方法,这个方法需要处理异常
                Date newDate = sdf.parse(date);
                System.out.println(newDate);
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
    ​
        }
    }
    ​
    运行结果:;
    Tue Jan 01 19:30:00 CST 2008
  • 如果我们想获取一个时间对于的星期几,这时候需要借助日历类,例如:

    public class Test {
        public static void main(String[] args) {
    ​
            // 获取系统当前时间
            Date date = new Date();
    ​
            // 获取日历对象
            Calendar c = Calendar.getInstance();
    ​
            // 让日历对象关联时间
            c.setTime(date);
    ​
            System.out.println("系统当前时间:" + date);
    ​
            System.out.println("一周的第几天:" + c.get(Calendar.DAY_OF_WEEK));
    ​
            System.out.println("一个月的第几天:" + c.get(Calendar.DAY_OF_MONTH));
    ​
        }
    }
    ​
    运行结果:;
    系统当前时间:Wed Aug 17 10:34:50 CST 2022
    一周的第几天:4
    一个月的第几天:17

    这个为什么是第四天呢?因为国外的一周第一天是星期日。

数学类

public class Test {
    public static void main(String[] args) {
​
        // java.util.Math 数学工具类
​
        // 计算平方根
        System.out.println("9的平方根:" + Math.sqrt(9));
​
        // 计算立方根
        System.out.println("8的立方根:" + Math.cbrt(8));
​
        // 计算x的y次方
        System.out.println("2的3次方:" + Math.pow(2,3));
​
        // 计算最大值
        System.out.println("1和2的最大值:" + Math.max(1,2));
​
        // 计算最小值
        System.out.println("1和2的最小值:" + Math.min(1,2));
​
        // 计算绝对值
        System.out.println("-1的绝对值:" + Math.abs(-1));
​
        // 向上取整
        System.out.println("10.2向上取整:" + Math.ceil(10.2));
​
        // 向下取整
        System.out.println("10.99向下取整:" + Math.floor(10.99));
​
        // 四舍五入返回double类型
        System.out.println("10.4四舍五入返回double类型:" + Math.rint(10.4));
        System.out.println("10.5四舍五入返回double类型:" + Math.rint(10.5));
​
        // 四舍五入返回int类型
        System.out.println("10.4四舍五入返回int类型:" + Math.round(10.4));
        System.out.println("10.5四舍五入返回int类型:" + Math.round(10.5));
​
    }
}
​
运行结果:
9的平方根:3.0
8的立方根:2.0
2的3次方:8.0
1和2的最大值:2
1和2的最小值:1
-1的绝对值:1
10.2向上取整:11.0
10.99向下取整:10.0
10.4四舍五入返回double类型:10.0
10.5四舍五入返回double类型:10.0
10.4四舍五入返回int类型:10
10.5四舍五入返回int类型:11

数字类

  • 这里主要掌握两个类:java.text.DecimalFormat (数字格式化显示方面)和java.math.BigDecimal(财务数据处理方面)。

    public class Test {
        public static void main(String[] args) {
    ​
            // 创建数字格式化对象
            // ###,###.## 表示数字加入千分位,保留两位小数
            DecimalFormat df = new DecimalFormat("###,###.##");
            String str = df.format(123456.789);
            System.out.println(str);
    ​
            // 小数部分保留两位,四舍五入
            DecimalFormat df2 = new DecimalFormat(".00");
            String str2 = df2.format(123.5489);
            System.out.println(str2);
    ​
        }
    }
    ​
    运行结果:;
    123,456.79
    123.55
    public class Test {
        public static void main(String[] args) {
    ​
            // 创建两个个精度较高的对象
            BigDecimal v1 = new BigDecimal(100);
            BigDecimal v2 = new BigDecimal(200);
    ​
            // 求和方法
            BigDecimal x1 = v1.add(v2);
            System.out.println(x1);
    ​
            // 乘积方法
            BigDecimal x2 = v1.multiply(v2);
            System.out.println(x2);
            
            // 这里只说了求和与乘积的方法,当然还有其他的方法,大家可以去查文档进行学习
    ​
        }
    }
    ​
    运行结果:
    300
    20000

随机数

public class Test {
    public static void main(String[] args) {
​
        // 在Java中可以专门生成随机数,java.util.Random
​
        // 创建一个随机生成器对象
        Random r = new Random();
        System.out.println("返回一个int类型随机数:" + r.nextInt());
​
        // 生成五个int类型的随机数,范围在0~100之间
        for (int i=0;i<5;i++){
            int v = r.nextInt(100);
            System.out.print(v + " ");
        }
​
        System.out.println();
​
        // 生成五个int类型的随机数,范围在0~10之间
        for (int i=0;i<5;i++){
            int v = r.nextInt(6);
            System.out.print(v + " ");
        }
​
    }
}
​
运行结果:;
返回一个int类型随机数:-178658592
40 1 65 55 75 
2 2 5 2 1 
  • 通过以上程序发现,区间越小,重复也高。假设现在有一个需求,在0~4之间生成5个不同的随机数,这应该怎么去实现呢?

    public class Test {
        public static void main(String[] args) {
    ​
            // 创建随机生成器对象
            Random random = new Random();
    ​
            // 准备一个容量为5的int类型的数组
            // 元素初始值为-1,如果为0的话,随机数中可以能有0,可能程序出错
            int[] arr = new int[]{-1,-1,-1,-1,-1};
    ​
            // 从数组的第一个下标开始放元素
            int index = 0;
            while (index < arr.length){
                // 生成随机数
                int value = random.nextInt(5);
                // 如果数组中不包含随机数,放进数组中
                if (!(query(arr,value))){
                    arr[index++] = value;
                }
            }
    ​
            // 输出结果
            System.out.println(Arrays.toString(arr));
        }
    ​
        /**
         * 查询数组中是否包含value随机数
         * @param arr 数组
         * @param value 查询元素
         * @return true包含 , false不包含
         */
        public static boolean query(int[] arr , int value){
            for (int i=0;i<arr.length;i++){
                if (arr[i] == value){
                    return true;
                }
            }
            return false;
        }
    ​
    }
    ​
    运行第一次结果:
    [0, 4, 3, 2, 1]
    ​
    运行第二次结果:
    [4, 0, 1, 2, 3]
    ​
    运行第三次结果:
    [1, 0, 3, 2, 4]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值