java入门基础七(常用类)

11. 常用类

11.1 基本数据类型包装类

含义:基本数据类型对应的类

出现的原因:Java为纯面向对象语言(万物皆对象),而8种基本数据类型不能创建对象,破坏了Java为纯面向对象语言的特征,所以Java又给这8种基本数据类型分别匹配了对应的类,这种叫做包装类/封装类。

继承关系:

基本数据类型引用数据类型继承关系
byteByteextends Number extends Object
shortShortextends Number extends Object
intIntegerextends Number extends Object
longLongextends Number extends Object
floatFloatextends Number extends Object
doubleDoubleextends Number extends Object
charCharacterextends Object
booleanBooleanextends Object

重点记忆:

  1. 数值型都继承Number。
  2. int的包装类Integer。
  3. char的包装类Character。

11.1.1 装箱

基本数据类型 -> 包装类

示例 int --> Integer

int i=100;
Integer integer = Integer.valueOf(i);
System.out.println(integer);//100
//能够直接输出integer,因为在Integer类中,toString方法已经被重写。

自动装箱:(在JDK1.5及之后,能够实现自动装箱和自动拆箱,但底层原理依旧是与装箱和拆箱相同)

示例:

int i = 100;
Integer integer = i;		//自动装箱(底层实现:Integer.valueOf(i);)
System.out.println(integer);//100

11.1.2 拆箱

包装类 -> 基本数据类型

示例 Integer --> int

Integer integer = new Integer(100);
int i = integer.intValue();  //拆箱
System.out.println(i);       //100

自动拆箱:(与自动装箱相同)

Integer integer = new Integer(100);
int i = integer;//拆箱
System.out.println(i);   //100

11.1.3 包装类底层源码

示例:

Integer integer1 = Integer.valueOf(100);
Integer integer2 = Integer.valueOf(100);
System.out.println(integer1 == integer2);    //true
				
Integer integer3 = Integer.valueOf(200);
Integer integer4 = Integer.valueOf(200);
System.out.println(integer3 == integer4);    //false

Character character1 = Character.valueOf('a');
Character character2 = Character.valueOf('a');
System.out.println(character1==character2);  //true
		
Character character3 = Character.valueOf('男');
Character character4 = Character.valueOf('男');
System.out.println(character3==character4);  //false

解释:

结果分析:

​ “==”符号用于引用数据类型时,比较的是对象所在的地址,证明integer1和integer2两个引用指向的是一个相同的地址,而character1和character2也是如此,但是剩下的integer3和integer4、character3和character4却截然相反,返回的false表面了他们的地址并不一样。
原因:

​ 这是因为在Integer和Character两个类中,存在一个静态内部类(缓存类),在这个静态内部类中定义有一个类的数组,存储了-128127的Integer对象(0127的Character对象),当调用valueOf()方法时,会首先判断数据是否在已经在数组中定义,如果已经定义,则会直接返回数组中对应的地址,这导致他们的地址是一样的。如果不在其中,才会new一个新的Integer(Character)对象。

底层源码展示(以Integer为例):

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

//静态内部类
private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
         if (integerCacheHighPropValue != null) {
             try {
                 int i = parseInt(integerCacheHighPropValue);
                 i = Math.max(i, 127);
                 // Maximum array size is Integer.MAX_VALUE
                 h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
              } catch( NumberFormatException nfe) {
                 // If the property cannot be parsed into an int, ignore it.
              }
         }
         high = h;

         cache = new Integer[(high - low) + 1];
         int j = low;
         for(int k = 0; k < cache.length; k++)
             cache[k] = new Integer(j++);

         // range [-128, 127] must be interned (JLS7 5.1.7)
          assert IntegerCache.high >= 127;
     }
    private IntegerCache() {}
}

11.2 字符串类

11.2.1 String类

String是一个不可变的类, 即一旦一个String对象被创建, 包含在这个对象中的字符序列是不可改变的, 直至该对象被销毁。

示例:将其他类型转换为字符串类型

int i = 100;
System.out.println(String.valueOf(i));//100
		
boolean bool = true;
System.out.println(String.valueOf(bool));//true 

注:虽然看起来输出没有变化,但类型已经改变。

String类的一些常用方法:
  1. 在字符串末尾追加字符串,并返回新的字符串

    String str1="adcde";
    str1 = str1.concat("12345");//  adcde12345
    
  2. 传入的下标处(包括)截取到字符串末尾,并返回新的字符串

    String str1="adcde";
    str1 = str1.substring(2);   //cde
    
  3. 截取开始下标(包括)和结束下标(不包括)之间的字符串

    String str1="adcdefgh";
    str1 = str1.substring(2,6);  //cdef
    
  4. 字符串中的字母转大小写

    String str1="adcdefgh";
    str1 = str1.toUpperCase();//转大写,ADCDEFGH
    str1 = str1.toLowerCase();//转小写,adcdefgh
    
  5. 去除字符串首尾空格

    String str1="   ad c de fg h    ";
    str1 = str1.trim();    //ad c de fg h
    
  6. 替换字符

    String str="   ad cc aade fgc h    ";
    str = str.replace('c', '-');  //   ad -- aade fg- h    
    
  7. 替换字符串

    String str="   ad cc aade fgc h    ";
    str = str.replaceFirst("a", "#");//替换第一个出现的字符串,并返回新的字符串
    System.out.println(str);   //   #d cc aade fgc h    
    str = str.replaceAll("c", "@");//替换字符串,并返回新的字符串
    System.out.println(str);   //   #d @@ aade fg@ h  
    str = str.replaceAll(" ", "");//替换字符串,并返回新的字符串
    System.out.println(str);   //#d@@aadefg@h
    
  8. 判断两个字符串内容是否相同

    String str="abcDefG";
    //equals区分大小写
    System.out.println(str.equals("abcDefG"));  //true 
    System.out.println(str.equals("abcdefg"));  //false
    //equalsIgnoreCase不区分大小写   (使用场景:验证码)
    System.out.println(str.equalsIgnoreCase("abcdefg"));  //true
    
  9. 判断此字符串是否以某个字符串开头/结尾

    String str="abcDefG";
    //判断开头字符串
    System.out.println(str.startsWith("a"));//true
    System.out.println(str.startsWith("A"));//false
    //判断结尾字符串
    System.out.println(str.endsWith("G"));  //true
    
  10. 查询此字符串第一次在目标字符串中的下标:

    String str="afaffgfgajjkfds";
    System.out.println(str.indexOf("f"));//1
    
  11. 查询此字符串最后一次在目标字符串中的下标

    String str="afaffgfgajjkfds";
    System.out.println(str.lastIndexOf("a"));//8
    
  12. 获取指定下标上的字符

    String str="afaffgfgajjkfds";
    System.out.println(str.charAt(8));  //a
    

11.2.2 StringBuilder类

StringBuilder代表可变的字符序列。又称为字符串缓冲区.

工作原理:

预先申请一块内存,存放字符序列,
如果字符序列满了,会重新改变缓存区的大小,以容纳更多的字符序列。
StringBuilder是可变对象,这个是String最大的不同。

继承关系:StringBuilder extends AbstractStringBuilder

创建示例:

//调用无参构造,默认创建的大小为16个字符
StringBuilder sb = new StringBuilder();
		
//自定义字符串缓冲区:100个字符
StringBuilder sb1 = new StringBuilder(100);
			
//自定义字符串缓冲区:"abcdef".length() + 16 : 22个字符
StringBuilder sb2 = new StringBuilder("abcdef");

底层源码展示:

//无参构造
public StringBuilder() {
   super(16);
 }
//有参构造(int类型)
public StringBuilder(int capacity) {
   super(capacity);
}
//有参构造(String类型)
public StringBuilder(String str) {
   super(str.length() + 16);
   append(str);
}
StringBuilder类常用的一些方法
  1. 在末尾追加字符串

    StringBuilder sb2 = new StringBuilder("abcdef");
    sb2.append("#####");
    System.out.println(sb2);  //abcdef#####
    
  2. 在指定下标处插入字符串

    StringBuilder sb2 = new StringBuilder("abcdef");
    sb2.insert(2, "###");
    System.out.println(sb2); //ab###cdef
    
  3. 替换指定下标上的字符

    StringBuilder sb2 = new StringBuilder("abcdef");
    sb2.setCharAt(3, '&');
    System.out.println(sb2);  //abc&f
    
  4. 从开始下标处(包含)替换到结束下标处(不包含)的字符串

    StringBuilder sb2 = new StringBuilder("abcdef");
    sb2.replace(2, 4, "$$$$$");
    System.out.println(sb2);  //ab$$$$$ef
    
  5. 删除指定下标上的字符

    StringBuilder sb2 = new StringBuilder("abcdef");
    sb2.deleteCharAt(1);
    System.out.println(sb2);  //acdef
    
  6. 从开始下标处(包含)删除到结束下标处(不包含)的字符串

    StringBuilder sb2 = new StringBuilder("abcdef");
    sb2.delete(2,4);
    System.out.println(sb2);  //abef
    
  7. 反转字符串

    StringBuilder sb2 = new StringBuilder("abcdef");
    sb2.reverse();
    System.out.println(sb2);  //fedcba
    

注:StringBuilder是可变的对象,因此只需要在原对象基础上操作,并不会向String一样需要new新的对象,因此,使用StringBuilder对象进行字符串的各种频繁操作时,执行效率比String更加高。

示例:

// 获取自1970.1.1 0:0:0到现在的毫秒数
long startTime = System.currentTimeMillis();
String str = "abc";
for (int i = 0; i < 50000; i++) {
	str += "aaa";
	// str = str + "abc"
	// str = new StringBuilder(str).append("abc").toString();
}
long endTime = System.currentTimeMillis();
System.out.println("消耗时长:" + (endTime - startTime));// 5746

// 获取自1970.1.1 0:0:0到现在的毫秒数
long startTime1 = System.currentTimeMillis();
StringBuilder sb = new StringBuilder("abc");
for (int i = 0; i < 50000; i++) {
	sb.append("bbb");
}
long endTime1 = System.currentTimeMillis();
System.out.println("消耗时长:" + (endTime1 - startTime1));// 5

效率提升近千倍。

11.2.3 StringBuffer类

​ StringBuffer与StringBuilder基本类似, AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,其中方法调用也一模一样,但唯一不同之处在于是否多线程安全

​ StringBuffer 类中,对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。而StringBuilder则没有,所以在使用多线程的情况下,为保证安全,使用StringBuffer类,如果是单线程,使用StringBuilder效率则要高于StringBuffer。

11.3 正则表达式

含义:用来描述或者匹配一系列符合某个语句规则的字符串。

Pattern:代表正则表达式的匹配模式

Matcher:提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持

示例1:(隐藏电话号中间四位)

String str="小红:13333335950,小明:1355551082";
		
//正则表达式的字符串
String regex = "(\\d{3})(\\d{4})(\\d{4})";

String replaceAll = str.replaceAll(regex, "$1****$3");
System.out.println(replaceAll);
//小红:133****5950,小明:1355551082

示例2:(校验QQ邮箱)

String str = "1445584980@qq.com";
		
//正则表达式的字符串
String regex = "\\d{5,10}@qq.com";   //5~10位数字开头
boolean matches = str.matches(regex);
System.out.println(matches);

示例3:(分隔路径)

String str="C:\\相册\\图片\\1.png";
String regex =":?\\\\";
//String[] split = str.split(regex);
//底层原理
Pattern pattern = Pattern.compile(regex);//获取正则表达式的对象
String[] split = pattern.split(str);//分隔
for (String string : split) {
    System.out.println(string);
}
/*
C
相册
图片
1.png
*/

示例4:(找到前端代码中的图片路径)

String str = "<img src='hhy/aaa.jpg'/><div><div/> <input type='image' src='submit.gif' /><img src='bbb.jpg'/>";

//正则表达式的字符串
String regex = "<img\\b[^>]*\\bsrc\\b\\s*=\\s*('|\")?([^'\"\n\r\f>]+(\\.jpg)\\b)[^>]*>";

//获取正则表达式对象
Pattern pattern = Pattern.compile(regex);
//获取匹配结果的对象
Matcher matcher = pattern.matcher(str);

//遍历查找
while(matcher.find()){
    String group = matcher.group(2);//获取匹配结果
    System.out.println(group);
}

常用的正则表达式:

验证手机号:

/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/

验证身份证号

 /^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/

验证邮政编码

/^[1-9]\d{5}$/

11.4 关于日期的类

11.4.1 Date类

Date–日期类

使用示例:

Date date = new Date();
//星期  月份 日期 时:分:秒  时区   年份
//Thu   Aug 05  19:37:06 CST   2021
System.out.println(date);

//自1970.1.1 0:0:0 往后推1000毫秒的时间
Date date = new Date(1000);
//Thu Jan 01 08:00:01 CST 1970
System.out.println(date);
11.4.2 SimpleDateFormat类

SimpleDateFormat --格式化日期的类,配合Date类使用

使用示例:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
		
//将Date 转 字符串
String format = sdf.format(new Date());
System.out.println(format);   //2021年08月05日 19:41:42

///将字符串 转 Date
Date date = sdf.parse("2021年08月05日 19:41:42"); 
System.out.println(date);  //Thu Aug 05 19:41:42 CST 2021
11.4.3 Calendar类

Calendar—日历类

使用示例:

//获取日历类的对象
Calendar c = Calendar.getInstance();

//获取单个的日历信息
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+1;//月份0~11
int day = c.get(Calendar.DAY_OF_MONTH);
int hour = c.get(Calendar.HOUR);
int minute = c.get(Calendar.MINUTE);
int second = c.get(Calendar.SECOND);

System.out.println(year);
System.out.println(month);
System.out.println(day);
System.out.println(hour);
System.out.println(minute);
System.out.println(second);

注:在只需要使用单个日期或时间信息时,Calendar更加方便,需要获取详细日期时间信息时,使用Date类和SimpleDateFormat类更加方便。

11.5 Math类

Math类为final类,不可被继承,并且他的所有的成员变量和方法都是static的,可通过类名调用,Math类中包含执行基本数字运算和几何函数的方法

常用方法:

  1. 取出一个0~1的随机值(包括0,不包括1)

    System.out.println(Math.random());
    
    //求一个1~100的随机数
    int rand =(int)(Math.random()*100)+1;
    System.out.println(rand);
    
  2. 求数的平方根

    System.out.println(Math.sqrt(9));  //3.0
    
  3. 求数的平方

    System.out.println(Math.pow(2, 4));  //16.0
    
  4. 向上取整数

    System.out.println(Math.ceil(1.32));  //2.0
    
  5. 向下取整数

    System.out.println(Math.floor(1.32));  //1.0
    
  6. 求最大值 最小值

    System.out.println(Math.max(3, 6));  //6
    System.out.println(Math.min(3, 6));   //3
    
  7. 四舍五入(只针对小数点后一位)

    System.out.println(Math.round(1.49));  //1.0
    
  8. 求绝对值

    System.out.println(Math.abs(-4)); //4
    
    //注意:abs也可能返回一个负数,当值超越int范围时。
    System.out.println(Math.abs(Integer.MAX_VALUE+1)); //-2147483648       Integer.MAX_VALUE=2147483647
    

拓展:静态导入

示例:导入Math类

/*
将Math类中所有的静态属性和静态方法都导入Test04这个类中;
把导入的静态属性和静态方法都认为是当前类自己的内容。
*/
import static java.lang.Math.*;  

使用Math的方法时,不在需要使用类名调用,可以直接使用方法名,编译时会首先就近查找本类,再查找Math类。

注:

如果本类中有和静态导入类相同的方法,会就近调用本类中的方法。

11.6 Random类

随机类,随机获取数值(int,byte[],double,long,float)

简单使用示例:

//创建随机类
Random ran = new Random();

//取出一个随机数
System.out.println(ran.nextInt());
		
//取出一个0~指定数(不包括此数)之间的随机数
int i =10;
System.out.println(ran.nextInt(10)); //0~9
		
//取出一个随机的Boolean值
System.out.println(ran.nextBoolean());

//取出一个随机的byte数组
byte[] bytes =new byte[5];
ran.nextBytes(bytes);
for (byte b : bytes) {
    System.out.println(b);
}

实例:(点名器)

public static void main(String[] args) {
    //创建随机雷的对象
    Random ran= new Random();

    //设置点名字符数组
    String [] names=new String[]{"小强","小花","小刚","小红","小明"};
    //获取0~人数之间的随机数
    int index = ran.nextInt(names.length);
    System.out.println("随机选出的人是:"+names[index]);
}

深入Random类源码:

//Random的无参构造
public Random() {
    this(seedUniquifier() ^ System.nanoTime());
}

//Random的有参构造
public Random(long seed) {
    if (getClass() == Random.class)
        this.seed = new AtomicLong(initialScramble(seed));
    else {
        // subclass might have overriden setSeed
        this.seed = new AtomicLong();
        setSeed(seed);
    }
}

在Random类中,生成的伪随机数,依赖于种子数,无参构造方法中种子数由seedUniquifier() ^ System.nanoTime()得到,再传递给有参构造函数。

当调用有参构造时,如果种子数固定,产生的随机数也将固定。

Random ran= new Random(10);

11.7 Runtime类

Runtime类为运行环境类,能够获取运行环境对象

基本使用示例:

//获取运行环境对象
Runtime run = Runtime.getRuntime();

System.out.println("获取最大内存数(字节):" + run.maxMemory());
System.out.println("获取闲置内存数(字节):" + run.freeMemory());
System.out.println("获取处理数:" + run.availableProcessors());

使用实例:(测试程序效率 时间+内存)

Runtime run = Runtime.getRuntime();
long startTime = System.currentTimeMillis();
long startMemory = run.freeMemory();
/*
	测试的程序代码块
*/
long endMemory = run.freeMemory();
long endTime = System.currentTimeMillis();
System.out.println("运行程序消耗的时长:" + (endTime-startTime));
System.out.println("运行程序消耗的内存:" + (startMemory-endMemory));

注:

  如果程序代码消耗的内存过多,导致jvm回收掉垃圾的内存,会让最终计算的内存增多。

11.8 System类

System类为系统类,最常使用的是系统标准的输入输出流。

  1. 系统标准的输入流

    //系统标准的输入流(方向:控制台 -> 程序)
    InputStream in =System.in;
    Scanner scan = new Scanner(in);
    String next = scan.next();
    //关闭资源
    scan.close();
    
  2. 系统标准的输出流

    //系统标准的输出流(方向:程序 -> 控制台)
    PrintStream out =System.out;
    out.println(next);
    
    //系统标准的错误输出流(方向:程序 -> 控制台)
    PrintStream err = System.err;
    err.println(next);
    
  3. 获取系统参数的对象

    //获取系统参数的对象
    Properties properties = System.getProperties();
    System.out.println(properties);
    
  4. 通过键获取值

    //通过键获取值
    String value = System.getProperty("os.name");  
    System.out.println(value);  //Windows 10(电脑操作系统)
    
  5. 退出当前虚拟机

    System.exit(0);
    //其后的任何代码将不会被执行。
    

注:

  1. 错误输出流采用的字体颜色为红色。

  2. 虽然System的out和err都为输出流,但是却是两个不同的线程,这两个线程共同争夺CPU资源,输出顺序与代码顺序无关。

    System.out.println("1");
    System.err.println("2");
    System.out.println("3");
    /*
    输出顺序随机,但“1”和“3”是在同一个线程,所以“1”始终在“3”之前输出。
    “2”的位置随机。
    */
    

11.9 大数值运算类

含义:用于大数值的运算。

11.9.1 BigInteger类

整数类型的大数值运算类

常用方法:

  1. 相加

    //整数类型的大数值运算
    BigInteger big1 = new BigInteger("123456789987654321");
    BigInteger big2 = new BigInteger("123456789987654321");
    
    //相加
    BigInteger add = big1.add(big2);
    System.out.println(add);//246913579975308642
    
  2. 相减

    //相减
    BigInteger subtract = big1.subtract(big2);
    System.out.println(subtract);    //0
    
  3. 相乘

    //相乘
    BigInteger multiply = big1.multiply(big2);
    
    System.out.println(multiply);//15241578994055784200731595789971041
    
  4. 相除

    //相除
    BigInteger divide = big1.divide(big2);//1
    System.out.println(divide);
    

11.9.2 BigDecemal类

小数类型的大数值运算类(精确)

常用方法:

  1. 相加

    BigDecimal big1 = new BigDecimal("1.5");
    BigDecimal big2 = new BigDecimal("0.4");
    BigDecimal big3 = new BigDecimal("0.3");
    
    //相加
    BigDecimal add = big1.add(big2);
    System.out.println(add); //1.9
    
  2. 相减

    //相减
    BigDecimal subtract = big1.subtract(big2);
    System.out.println(subtract); //1.1
    
  3. 相乘

    //相乘
    BigDecimal multiply = big1.multiply(big2);
    System.out.println(multiply);  //0.60
    
  4. 相除

    //相除
    BigDecimal divide = big1.divide(big2);
    System.out.println(divide);//3.75
    
    //设置保留的小数位和保留方式。
    BigDecimal divide2 = big2.divide(big3, 3, BigDecimal.ROUND_HALF_UP);
    System.out.println(divide2);//1.333
    

    注:在进行小数类型的大数值除法时,如果除不尽,将会出现运行报错, java.lang.ArithmeticException,这时必须使用第二种相除方式。

    常见的保留方式:

    BigDecimal.ROUND_HALF_UP:四舍五入

    BigDecimal.ROUND_CEILING: 舍去小数位,往正无穷方向移动 1.1->2 1.8->2 -1.1->-1 -1.8->-1

    BigDecimal.ROUND_DOWN: 舍去小数位 ,向0的方向移动1.1->1 1.5->1 1.8->1 -1.1->-1 -1.5->-1 -1.8>-1

    BigDecimal.ROUND_FLOOR: 舍去小数位,往负无穷 1.1->1 1.5->1 1.8->1 -1.1->-2 -1.5->-2 -1.8->-2

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值