zoukankan      html  css  js  c++  java
  • java入门篇7 --- java核心类

    1. String

    字符串是我们常用的引用类型的数据结构,看一下用法:

    public class HelloWorld {
        public static void main(String[] args) {
            String s1 = " hello world ";
            String s2 = " HELLO WORLD ".toLowerCase();
            // 字符串的比较使用equals
            System.out.println(s1 == s2);  // false
            System.out.println(s1.equals(s2));  // true
            // 获取第一个指定字母的下表
            System.out.println(s1.indexOf("l"));  // 3
            // 获取该字符串出现的最后一个指定字母的下表
            System.out.println(s1.lastIndexOf("l")); // 10
            // 字符串是否以。。。开头
            System.out.println(s1.startsWith("l"));  // false
            // 字符串是否以...结尾
            System.out.println(s1.endsWith("l"));  // false
            // 提取字符串的子串
            System.out.println(s1.substring(0, 2));  // " h"
            System.out.println(s1.substring(1, 3)); // " he"
            // 去除首位空白
            System.out.println(s1.trim());  // "hello world"
            // 去除开头空白
            System.out.println(s1.stripLeading());  // "hello world "
            // 去除结尾空白
            System.out.println(s1.stripTrailing()); // " hello world"
            // 判断是否为空
            System.out.println(s1.isEmpty());  // false
            System.out.println("".isEmpty());  // true
            // 判断是否是空白字符串
            System.out.println(s1.isBlank()); // false
            System.out.println(" ".isBlank()); // true
            // 替换字符串
            System.out.println(s1.replace('l', 'L'));  // " heLLo worLd "  这个是字符
            System.out.println(s1.replaceAll("l", "L"));  // " heLLo worLd "  这个是字符串,使用正则表达式的字符串
            // 分割字符串
            String[] c = s1.split(" ");
            System.out.println(c);  // [Ljava.lang.String;@77459877
            for (String d : c) {
                System.out.println(d);  // ["", "hello", "world"]
            }
            // 拼接字符串
            System.out.println(String.join(" ", c));  // " hello world"
            // 类型转换
            System.out.println(String.valueOf(123));  // "123"
            System.out.println(String.valueOf(45.67));  // "45.67"
            System.out.println(String.valueOf(true));  // "true"
            // 字符串转数字
            int n = Integer.parseInt("123");
            System.out.println(n);  // 123
            // 字符串转化为 char[]
            char[] cc = s1.toCharArray();
            System.out.println("---");
            System.out.println(cc);  //  hello world 输出的时候自动把这个列表打印成字符串了
            System.out.println("---");
            for (char m : cc) {
                System.out.println(m);  // [" ", "h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d", " "]
            }
            // char[] 可以转化为字符串,那么转变完成之后,在修改char[]是否会影响字符串呢
            char[] ccc = new char[]{'a', 'b', 'c'};
            String cs = new String(ccc);
            System.out.println(cs);  // abc
            ccc[0] = 'd';
            System.out.println(ccc[0]); // d
            System.out.println(cs);  // abc
        }
    }

    java对String做了特殊处理,因此我们可以直接使用 + 来拼接字符串,但理论上每次拼接字符串,都会生成一个新的字符串,这样会浪费内存,因此java的标准库中提供了StringBuilder,我们首先来看一下源码,大部分的具体实现在这AbstractStringBuilder类中,可以自行去看,基本就是找位置,增删改查操作

    // 这不就是上篇说的继承
    public final class StringBuilder
            extends AbstractStringBuilder
            implements java.io.Serializable, Comparable<java.lang.StringBuilder>, CharSequence
    {
    
        // 这个就是初始化,方法重载,如果不穿值默认是16,可不传或者 int String CharSequence, 篇幅较长,省略一下
        @HotSpotIntrinsicCandidate
        public StringBuilder() {
            super(16);
        }
        
        @HotSpotIntrinsicCandidate
        public StringBuilder(int capacity) {
            super(capacity);
        }
        ...
    
    
        // 这个就是方法重写,做比较的,字串穿比较
        @Override
        public int compareTo(java.lang.StringBuilder another) {
            return super.compareTo(another);
        }
    
        // 方法重写,这个就是添加操作,当传入的是对象,获取对象的值,然后调用值类型对应的append的方法签名,观察下面的append,发现最后是把this返回去了
        // 这个append可以添加各种类型,源码就不一一贴出来了,可以自己去看
        @Override
        public java.lang.StringBuilder append(Object obj) {
            return append(String.valueOf(obj));
        }
    
        @Override
        @HotSpotIntrinsicCandidate
        public java.lang.StringBuilder append(String str) {
            super.append(str);
            return this;
        }
        ...
        
        // 删除操作。可以看出来,他这个就是告诉起止位置,然后进行删除操作
        @Override
        public java.lang.StringBuilder delete(int start, int end) {
            super.delete(start, end);
            return this;
        }
        // 删除指定位置
        @Override
        public java.lang.StringBuilder deleteCharAt(int index) {
            super.deleteCharAt(index);
            return this;
        }
    
        // 替换,告诉起止位置,以及字符串
        @Override
        public java.lang.StringBuilder replace(int start, int end, String str) {
            super.replace(start, end, str);
            return this;
        }
    
    
        // 这个就是插入操作啦,第一位是告诉哦要插入的位置,后面就是根据不同类型做的一些操作,例如char[]可以告知你想要插入这个数组中的起止位置,
        // 有很多重载方法,就不一一贴出了
        @Override
        public java.lang.StringBuilder insert(int index, char[] str, int offset,
                                              int len)
        {
            super.insert(index, str, offset, len);
            return this;
        }
    
        @Override
        public java.lang.StringBuilder insert(int offset, Object obj) {
            super.insert(offset, obj);
            return this;
        }
        ...
        
        // 获取指定字符串的
        @Override
        public int indexOf(String str) {
            return super.indexOf(str);
        }
        // 只不过是多了个起始位置,获取下表
        @Override
        public int indexOf(String str, int fromIndex) {
            return super.indexOf(str, fromIndex);
        }
        // 获取指定字符串的最后一个下表
        @Override
        public int lastIndexOf(String str) {
            return super.lastIndexOf(str);
        }
        // 增加了一个位置
        @Override
        public int lastIndexOf(String str, int fromIndex) {
            return super.lastIndexOf(str, fromIndex);
        }
    
        // 反转
        @Override
        public java.lang.StringBuilder reverse() {
            super.reverse();
            return this;
        }
    
        // 获取字符串
        @Override
        @HotSpotIntrinsicCandidate
        public String toString() {
            // Create a copy, don't share the array
            return isLatin1() ? StringLatin1.newString(value, 0, count)
                    : StringUTF16.newString(value, 0, count);
        }
    }

    接下来,我们来具体时间使用一下这个

    public class HelloWorld {
        public static void main(String[] args) {
            StringBuilder s1 = new StringBuilder();
            StringBuilder s2 = new StringBuilder(1024);
            StringBuilder s3 = new StringBuilder("love");
            System.out.println(s1.toString());  //
            System.out.println(s2.toString()); //
            System.out.println(s3.toString()); // love  这个为什么会有呢,可以看当时提到的父类,他在穿字符串初始化时,实际上时判断字符串长度与integer的最大长度减16进行对比,然后在定义长度,并将值给他
            s1.append(1);
            s1.append(true);
            s2.append(String.valueOf(1));
            s3.append(new char[]{'1'});
            s3.append(new char[]{'1', '2', '3', '4'}, 1, 3);  // 开始位置,增加几位,注意这两个数之和,不要超过数组的长度
            System.out.println(s1.toString());  // 1true
            System.out.println(s2.toString()); // 1
            System.out.println(s3.toString()); // love1234
            s1.insert(1, "2");
            s2.insert(0, 10.58f);
            s3.insert(4, new char[]{'a'});
            System.out.println(s1.toString());  // 12true
            System.out.println(s2.toString()); // 10.581
            System.out.println(s3.toString()); // lovea1234
            System.out.println(s3.indexOf("1")); //  5
            System.out.println(s3.lastIndexOf("4", 3)); // -1
            s1.replace(0, 1, "3");  // 32true
            System.out.println(s1.toString());  // 3
    //        s1.delete(1,100);  // 超出范围就会报错
            s1.delete(1, 3);
            System.out.println(s1.toString());  // 3rue  删除顾头不顾维
    //        s2.deleteCharAt(1222);  // 超出范围就会报错
            s2.deleteCharAt(1);
            System.out.println(s2.toString());  // 1.581
        }
    }

    对于普通字符串的➕操作,编译器在编译时会帮助我们转化一个类,并在运行时帮助我们将其转化为StringBuilder,因此不需要考虑太多.

    对于我们常用的基本数据类型,不能赋值为null,那这些基本的数据类型对应的引用类型是哪些呢?

    基本类型对应的引用类型
    boolean java.lang.Boolean
    byte java.lang.Byte
    short java.lang.Short
    int java.lang.Integer
    long java.lang.Long
    float java.lang.Float
    double java.lang.Double
    char java.lang.Character

    如上述所说,都有对应引用类型,我们可以对这些类型之间进行相互转化

    public class HelloWorld {
        public static void main(String[] args) {
            int n = 10;
            Integer i = new Integer(n);  // 这种做法最不推荐,因为这样会实例化然后在做, Integer.valueOf(n) 有点浪费资源
            Integer i2 = Integer.valueOf(n);  // 因为Integer与int之间是自动封箱的,这个可以不用写,但如果需要写的话,推荐这样写,这样效率会高一些
            Integer i3 = n;
            int m = i2;
            System.out.println(i);  //10
            System.out.println(i2); // 10
            System.out.println(i3); // 10
            System.out.println(m);  //10
            System.out.println(Integer.parseInt("1234"));  // 1234 字符串转换
    
        }
    }

    javabean:

    javabean一般就是用过private来声明属性(我习惯叫属性,一般叫字段),然后通过public定义的方法来进行读写,并且格式遵循:读方法:get属性名,写方法:set方法名,一般情况下,我们在类中声明了private,可以在ideal中邮件直接创建读写方法,如果这个类中只包含读方法,那就说明这个类是只读类。

    为了跟上潮流,后续我就把这个属性改成叫字段啦

    另外,java提供了一个包,帮助我们枚举所有的字段跟方法,叫Introspector,就是枚举,这个感觉很实用,以后我们在进行搭建框架的时候,可以封装一个类来进行对应传入实例的调用,这个再次不进行演示了。

    import java.beans.Introspector;
    import java.beans.*;
    
    class Person{
        private String name;
        private int age;
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    public class HelloWorld {
        public static void main(String[] args) throws Exception {
           BeanInfo b = Introspector.getBeanInfo(Person.class);
           for(PropertyDescriptor n : b.getPropertyDescriptors()){
                System.out.println(n.getName());
                System.out.println(n.getReadMethod());
                System.out.println(n.getWriteMethod());
           }
            // age
            //public int Person.getAge()
            //public void Person.setAge(int)
            //class
            //public final native java.lang.Class java.lang.Object.getClass()
            //null
            //name
            //public java.lang.String Person.getName()
            //public void Person.setName(java.lang.String)
            System.out.println(new Person().getClass());  // class Person
        }
    }

    既然说到了枚举,那就不得不提及一下java里面的枚举类,关键字定义为enum,例如enum Weekend,他最终被被编译器翻译成finnal class Weekend extends Enum,因此我们定义的枚举类是不可继承的,

    枚举很实用跟swith搭配

    enum Weekend{
        // 这个括号中的内容可以不写,如果不写那么那个那个初始化也就不用xie
        Mon(1,"周一"), Tus(2,"周二"), Wen(3,"周三"), Thi(4,"周四"), Fri(5,"周五"), Sat(6,"周六"), Sun(7,"周日");
        public final  int num;
        private final  String str;
        private Weekend(int n, String s){
            this.num = n;
            this.str = s;
        }
        @Override
        public String toString(){
            return this.str;
        }
    }
    public class HelloWorld {
        public static void main(String[] args) throws Exception {
            Weekend mon = Weekend.Mon;
            System.out.println(mon.num);   // 1 这个是我们自己定义的
            System.out.println(mon.toString());  // 周一  定义的字段
            System.out.println(mon.ordinal());  // 0  这个就是下标,也就是顺序,因此一般我们在做这种操作时,尽量不要用这种方法来获取常量值,容易搞乱,比如我把Sun提到最前面,就又是一种结果
            System.out.println(mon.name()); // Mon  这个就是常量的字段名
            System.out.println(mon.equals(1));  // false  判断是否相等,请使用equals,可以看出,只有weekend.mon是相同的
            System.out.println(mon.equals("周一")); // false
            System.out.println(mon.equals("Mon"));  // false
            System.out.println(mon.equals(0));  // false
            System.out.println(mon.equals(Weekend.Mon));  // true
            switch (mon){
                case Sun:
                case Sat:
                    System.out.println("weekend");
                    break;
                case Mon:
                case Tus:
                case Wen:
                case Thi:
                case Fri:
                    System.out.println("weekday");
                    break;
                default:
                    System.out.println("not found");
                    break;
            }  // weekday
        }
    }

    java有很多常用的包,下面列举几个

    Math:

    public class HelloWorld {
        public static void main(String[] args) throws Exception {
            System.out.println(Math.abs(-99));  // 99 计算绝对值
            System.out.println(Math.max(1, 2));  // 2  计算最大值
            System.out.println(Math.min(1, 2));  // 1  计算最小值
            System.out.println(Math.pow(10, 2)); // 100  计算10的2次方
            System.out.println(Math.sqrt(2));  // 1.4142135623730951  计算指定数的平方
            System.out.println(Math.exp(1));  // 2.718281828459045 计算e的几次方
            System.out.println(Math.exp(2));  // 7.38905609893065
            System.out.println(Math.log(4));  // 1.3862943611198906 计算log的指定数
            System.out.println(Math.log10(100));  // 2.0
            System.out.println(Math.sin(5));  // -0.9589242746631385  计算sin
            System.out.println(Math.cos(5));  // 0.28366218546322625  计算 cos
            System.out.println(Math.tan(4));  // 1.1578212823495775  计算 tan
            System.out.println(Math.PI);  // 3.141592653589793 PI常量,圆周率
            System.out.println(Math.E);  // 2.718281828459045  e的常量
            System.out.println(Math.random());  // 0.4516913402063736 随机返回一个 0 至 1 的数
            System.out.println(Math.random());  // 0.4255472992888448
            System.out.println(Math.random());  // 0.7124471108227883
        }
    }

    Random

    import java.util.Random;
    
    public class HelloWorld {
        public static void main(String[] args) throws Exception {
            Random r = new Random();
            Random r1 = new Random(111);
            System.out.println(r.nextBoolean());  // true  随机获取boolean值
            System.out.println(r.nextInt());  // 1659406565 随机获取一个整数 
            System.out.println(r1.nextInt());  // -1196652709
            System.out.println(r.nextFloat());  //  0.5547011 随机获取[0,1]之间的浮点数
            System.out.println(r.nextDouble());  // 0.15836726706631754  随机获取[0,1]之间的double
            System.out.println(r.nextLong());  // -1408936196736804046 随机获取[0,1]之间的long
            System.out.println(r.nextInt(100));  // 98  随机获取一个从0 至100的整数
            System.out.println(r1.nextInt(10));  // 3 随机获取1个从 0 至10 的整数
            // random产生的是伪随机数,s每次得到的结构不同,但是s1每次的结果相同,为什么呢,因为我们为s1制定了一个种子,因此产生的序列不同
            // 而未被制定中的话,经看源码,根据系统的纳秒来进行初始化seed(种子),因此得到的值不同
    //        public Random() {
    //            this(seedUniquifier() ^ System.nanoTime());
    //        }
            StringBuilder s = new StringBuilder();
            StringBuilder s1 = new StringBuilder();
            for (int i = 0; i < 10; i++) {
                s.append(r.nextInt(100)).append(" ");
                s1.append(r1.nextInt(100)).append(" ");
            }
            System.out.println(s.toString());  // 5 84 31 75 83 14 75 80 72 39
            System.out.println(s1.toString());  // 57 97 9 20 84 12 97 65 60 34
        }
    }

    有伪随机数就有真随机数,加下来看一下安全性较的SecureRandom:

    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.util.Arrays;
    
    public class HelloWorld {
        public static void main(String[] args) throws Exception {
            SecureRandom sr = null;   // 不支持初始化种子
            try {
                sr = SecureRandom.getInstanceStrong();  // 获得高强度安全随机数生成器
            } catch (NoSuchAlgorithmException e) {
                sr = new SecureRandom();   // 普通安全随机数生成器
            }
            System.out.println(sr.nextInt());  // -1418568105
            System.out.println(sr.nextInt(100));  // 64
            byte[] b = new byte[32];
            sr.nextBytes(b);
            System.out.println(Arrays.toString(b)); // [-45, -101, 38, -113, -65, 2, 69, -116, 82, 26, -116, -22, 104, 58, -70, -92, 108, -13, 120, -44, 65, -90, -2, 73, -5, 50, -3, 116, -15, -60, 126, -50]
        }
    }
  • 相关阅读:
    Dubbo之SPI实现原理详解
    Java SPI详解
    Java是如何实现自己的SPI机制的
    Dubbo的负载均衡原理解析
    Dubbo公开课
    【todo】什么是沟子函数
    一步一图,带你走进 Netty 的世界!
    https://github.com/xiaojiaqi/k8seasy_release_page
    mysql 8.0导致5.6数据后 :ERROR 1449 (HY000): The user specified as a definer ('mysql.infoschema'@'localhost') does not exist
    Ansible 日常使用技巧
  • 原文地址:https://www.cnblogs.com/yangshixiong/p/12163234.html
Copyright © 2011-2022 走看看