JAVA常用类

目录

String 类

常用方法

StringBuffer类

八种基本包装类

自动装箱与自动拆箱

Integer类

String、int和Integer之间相互转换

 日期类

 日期格式化

利用System.currentTimeMillis()方法计算程序执行时间

数字格式化

BigDecimal类

常用构造方法

常用方法

BigDecimal大小比较

BigDecimal常见异常


String 类

  1. String表示字符串的类型,属于引用数据类型,不属于基本数据类型
  2. 在Java中随便使用双引号括起来的都是String对象。例如:“abc”
  3. java中规定,双引号括起来的字符串,是不可变的

 

在jdk中双引号括起来的字符串,例如:“abc” 都是直接存储在方法区的“字符串常量池”中的。

为什么呢?因为字符串在实际开发中使用太频繁,为了保证效率,所以把字符串放到了方法区的字符串常量池中

例如

public class Test{
    public static void main(String[] args) {
        String s1 = "abcdef";
        String s2 = "abcdef" + "xy";
        //new出的对象都是在堆里
        String s3 = new String("xy");
    }
}

内存结构图如图所示

当没有用new 开新对象时,要判断两个String引用类型指向的字符串内容是否相同,可以直接用“==”判断。

例如

public class Test{
    public static void main(String[] args) {
        String s1 = "abcdef";
        String s2 = "abcdef";
        if(s1 == s2){
            System.out.println("yes");
        }else{
            System.out.println("no");
        }
    }
}

因为,s1 和 s2 均指向字符串常量池中的"abcdef" 对象。

如果用new 的话,例如

public class Test{
    public static void main(String[] args) {
        String s1 = new String("abcdef");
        String s2 = new String("abcdef");
        if(s1 == s2){
            System.out.println("yes");
        }else{
            System.out.println("no");
        }
    }
}

则会输出no,因为s1 和 s2是指向了堆中的两个不同的string对象,这两个对象引用了字符串常量池中的同一个"abcdef"。

因此s1和s2的值是不同的,应该使用equals方法比较。

 

面试题:下面程序一共创建了几个字符串对象

答案:3个

public class Test{
    public static void main(String[] args) {
        String s1 = new String("abcdef");
        String s2 = new String("abcdef");
    }
}

第一个是字符串常量池中的String对象,还有两个是在堆里的String对象

 

常用方法

1.char charAt(int index)

返回索引处的字符

 

2.int compareTo(String anotherString)

按照字典序比较两个字符串

 

3.boolean contains(CharSequence s)

判断字符串里是否包含s

 

4.boolean endsWith(String suffix)

判断当前字符串是否以某个字符串结尾

 

5.boolean startsWith(String prefix)

判断当前字符串是否以某个字符串开头

 

6.boolean equalsIgnoreCase(String str)

判断两个字符串是否相等,忽略大小写

 

7.byte[] getBytes()

返回当前字符串的byte数组

 

8.int indexOf(String str)

判断某个字符串在当前字符串中第一次出现处的索引值

 

9.int lastIndexOf(String str)

判断某个字符串在当前字符串中最后一次出现的索引

 

10.String replace(CharSequence target, CharSequence replacement);

将当前字符串中的某个字符串替换为另一个字符串

 

11.String[] split(String regex)

将当前字符串按照regex分割为多个字符串

 

12.String substring(int beginindex) 参数是起始下标

截取起始下标之后的字符串

 

13.String substring(int beginindex,int endindex) 参数是起始下标和截止下标

截取beginindex和endindex之间的字符串,endindex不包含

 

14.char [] toCharArray()

将字符串转换为char数组

 

15.toLowerCase()

转小写

 

16.toUpperCase()

转大写

17.String trim()

去除字符串前后的空格

 

18.静态方法 String.valueOf(参数)

将参数转换成字符串

如果是String.valueOf(new 类名) 则会自动调用这个类的toString方法

 

StringBuffer类

StringBuffer 类是可变字符串类,创建 StringBuffer 类的对象后可以随意修改字符串的内容。每个 StringBuffer 类的对象都能够存储指定容量的字符串,如果字符串的长度超过了 StringBuffer 类对象的容量,则该对象的容量会自动扩大。

StringBuffer 类提供了 3 个构造方法来创建一个字符串,如下所示:

  • StringBuffer() 构造一个空的字符串缓冲区,并且初始化为 16 个字符的容量。
  • StringBuffer(int length) 创建一个空的字符串缓冲区,并且初始化为指定长度 length 的容量。
  • StringBuffer(String str) 创建一个字符串缓冲区,并将其内容初始化为指定的字符串内容 str,字符串缓冲区的初始容量为 16 加上字符串 str 的长度。

思考:实际开发中,如果需要进行字符串的拼盘拼接,会有什么问题?

因为java中的字符串是不可变的,每一次拼接都会产生新字符串,这样会占用大量方法区内存,造成内存空间的浪费。

例如

public class test{
    public static void main(String[] args) {
        String s1 = "a";
        s1 += "b";
        s1 += "c";
        s1 += "d";
    }
}
/*
首先String s1 = "a",会在字符串常量池中创建一个“a”的字符串对象
然后s1+="b" 此时s1 = “ab”,由于字符串常量池中没有"ab",所以它又会创建一个字符串对象
之后s1+="c" 和 s1+=“d” 均会创建一个字符串对象。于是字符串常量池中现在就有了四个对象,其中"ab","abc"均是中间产生了垃圾,占用了内存.

*/

 

String类之所以占用方法区内存是因为 String类底层使用final修饰的char数组实现的(java8),因此如果想进行拼接的话,就必须创建新的char数组因此创建新的字符串会占用方法区内存。原来存在的final修饰的char数组无法被释放

StringBuffer类就不一样了,它底层是用char数组实现的,所以StringBuffer类中的对象长度可变。

底层原理:StringBuffer类提供了append()方法来向当前字符串后添加字符串,每次添加会检查添加后字符串的长度是否超出了缓冲区的长度(实际上就是char数组的长度),如果超出了则创建一个更大的char数组,并进行数组的拷贝,拷贝完成后,原来的char数组就会被回收,并且由于char数组并没有被final修饰,所以它是保存在堆里的,是可以被释放的,并不会占用常量池中的内存。这样就节省了内存。

 

除此之外还有个StringBuilder类

使用StringBuilder也可以实现字符串的拼接,区别就是StringBuilder是非线程安全的,StringBuffer是线程安全的

 

八种基本包装类

java中为八种基本数据类型又对应准备了八种包装数据类型。他们是引用数据类型,父类是Object

这里有两个概念:拆箱和装箱

拆箱:将包装类转换为基本数据类型

装箱:将基本数据类型装欢为包装类

这是因为,有些时候方法的参数是Object引用类型,基本数据类型无法做参数,因此才有了八种包装数据类型

八种基本数据类型分别对应的包装类型

byteByte继承于Number
shortShort继承于Number
intInteger继承于Number
longLong继承于Number
floatFloat继承于Number
doubleDouble继承于Number
booleanBoolean继承于Object
charCharacter继承于Object

 

Number类

Number类中有很多方法是用来将包装类转换成基本数据类型,例如

bytebyteValue()

返回指定号码作为值 byte ,这可能涉及舍入或截断。

abstract doubledoubleValue()

返回指定数字的值为 double ,可能涉及四舍五入。

abstract floatfloatValue()

返回指定数字的值为 float ,可能涉及四舍五入。

abstract intintValue()

返回指定号码作为值 int ,这可能涉及舍入或截断。

abstract longlongValue()

返回指定数字的值为 long ,可能涉及四舍五入或截断。

shortshortValue()

返回指定号码作为值 short ,这可能涉及舍入或截断。

 

自动装箱与自动拆箱

装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。

优点:基本类型和引用类型可以直接运算,

缺点:容易引发空指针异常

public class test{
    public static void main(String[] args) {
        //自动装箱
       Integer x = 900;
       //自动调用toString方法
        System.out.println(x);
       //自动拆箱
       int y = x;
        
       //x自动拆箱为int类型,注意只有+ - * / %可以自动拆箱,== 不可以
        System.out.println(x+1);
    }
}

 

java中为了提高程序的执行效率,将[-128,127]之间所有的包装对象提前创建好,放到了方法区的“整数型常量池”中,目的是只要用这个区间的数据就不需要再new了,直接从整数型常量池中取出来。

验证:

public class test{
    public static void main(String[] args) {
       Integer a = 128;
       Integer b = 128;
        System.out.println(a==b);

        Integer x = 127;
        Integer y = 127;
        System.out.println(x==y);
    }
}

输出结果为

内存图如下所示

但是对于Double类型来说,我们就不能这样做,因为它在这个范围内个数是无限的。 
总结一句就是:在某个范围内的整型数值的个数是有限的,而浮点数却不是。

所以在Double里面的做法很直接,就是直接创建一个对象,所以每次创建的对象都不一样。

下面我们进行一个归类: 
Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。 
Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象。

下面对Integer派别进行一个总结,如下图: 
这里写图片描述

Integer类

常用方法

1.String转int

static int parseInt(String s)

String类型字符串转换为int,注意,s必须是一个文本数字

2.toString(int ,int 进制),将int整数转成指定的进制数

static String toString(Integer x, int radix)

//radix表示进制

 3.Integer的两个常量

int的最大值    Integer.MAX_VALUE

int的最小值    Integer.MIN_VALUE

4.Integer的构造方法

Integer(String s)

s必须是一个文本数字,不能含有其他符号 

Integer(int i)

 

 

String、int和Integer之间相互转换

 日期类

java.util.Date中提供了一个Date类来处理日期。

注意,是java.utile.Date,而不是java.sql.Date包,导包时候可能会导错。

 

创建一个当前时间的Date对象

Date d = new Date()

创建一个指定时间的Date对象

使用带参数的构造方法Date(int year, int month, int day) ,可以构造指定日期的Date类对象,Date类中年份的参数应该是实际需要代表的年份减去1900,实际需要代表的月份减去1以后的值。

//创建一个代表2014年6月12号的Date对象

Date d1 = new Date(2014-1900, 6-1, 12); (注意参数的设置)

正确获得一个date对象所包含的信息

 Date d2 =  new Date(2014-1900, 6-1, 12);

        //获得年份 (注意年份要加上1900,这样才是日期对象d2所代表的年份)

        int year = d2.getYear() + 1900;

        //获得月份  (注意月份要加1,这样才是日期对象d2所代表的月份)

        int month = d2.getMonth() + 1;

        //获得日期

        int date = d2.getDate();

        //获得小时

        int hour = d2.getHours();//不设置默认为0

        //获得分钟

        int minute = d2.getMinutes();

        //获得秒

        int second = d2.getSeconds();

   //获得星期 (注意:0代表星期日、1代表星期1、2代表星期2,其他的一次类推了)

int day = d2.getDay();

 

 日期格式化

Date类的默认格式是这样的

Sat Sep 19 15:36:25 CST 2020

不太适合中国人看,我们可以给它格式化

需要使用SimpleDateFormat类

 它可以实现按将日期按特定的格式转换为字符串

例如

import java.text.SimpleDateFormat;
import java.util.Date;

public class test{
    public static void main(String[] args) {
        Date nowTime = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String nowTimeStr = sdf.format(nowTime);
        System.out.println(nowTimeStr);

    }
}

输出为

 日期字符串转Date类型

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class test{
    public static void main(String[] args) throws ParseException {
        String s = "2020-9-19 15:47:30";
        //这里构造函数里的参数必须和字符串里的格式相同
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = sdf.parse(s);
        System.out.println(d);

    }
}

 

利用System.currentTimeMillis()方法计算程序执行时间

System.currentTimeMillis()获取自1970年1月1日 00:00:00 000到当前系统时间的总毫秒数

因此我们只需要在程序开始时取一次时间,结束时取一次时间即可计算出程序大体花费的时间

 

这里简单总结下System类的相关属性和方法

System.out  out是System类的静态变量

System.out.println()    println()方法不是System类的 而是PrintStream类的

System.gc() 建议启动垃圾回收器

System.currentTimeMillis() 获取自1970年1月1日 00:00:00 000到当前系统时间的总毫秒数

System.exit(0)    退出JVM

 

数字格式化

java提供了一个类——DecimalFormat类用来格式化数字

数字格式

0 一个数字 

# 一个数字,不包括 0 

. 小数的分隔符的占位符 

, 分组分隔符的占位符 

; 分隔格式。 

- 缺省负数前缀。 

% 乘以 100 和作为百分比显示 

? 乘以 1000 和作为千进制货币符显示;用货币符号代替;如果双写,用 国际货币符号代替。如果出现在一个模式中,用货币十进制分隔符代 替十进制分隔符。 

X 前缀或后缀中使用的任何其它字符,用来引用前缀或后缀中的特殊字符。

例如


DecimalFormat df1 = new DecimalFormat("0.0"); 
 
DecimalFormat df2 = new DecimalFormat("#.#"); 
 
DecimalFormat df3 = new DecimalFormat("000.000"); 
 
DecimalFormat df4 = new DecimalFormat("###.###"); 
 
System.out.println(df1.format(12.34)); //12.3
 
System.out.println(df2.format(12.34)); //12.3
 
System.out.println(df3.format(12.34)); //012.340
 
System.out.println(df4.format(12.34)); //12.34
import java.text.DecimalFormat;
 
public class Test{
    public static void main(String[] args){
        double pi=3.1415927;//圆周率
        //取一位整数 
        System.out.println(new DecimalFormat("0").format(pi));//3
        //取一位整数和两位小数  
        System.out.println(new DecimalFormat("0.00").format(pi));//3.14
        //取两位整数和三位小数,整数不足部分以0填补。  
        System.out.println(new DecimalFormat("00.000").format(pi));//03.142  
        //取所有整数部分  
        System.out.println(new DecimalFormat("#").format(pi));//3  
        //以百分比方式计数,并取两位小数  
        System.out.println(new DecimalFormat("#.##%").format(pi));//314.16%  
        
        long c=299792458;//光速  
        //显示为科学计数法,并取五位小数  
        System.out.println(new DecimalFormat("#.#####E0").format(c));//2.99792E8  
        //显示为两位整数的科学计数法,并取四位小数  
        System.out.println(new DecimalFormat("00.####E0").format(c));//29.9792E7  
        //每三位以逗号进行分隔。  
        System.out.println(new DecimalFormat(",###").format(c));//299,792,458  
        //将格式嵌入文本  
        System.out.println(new DecimalFormat("光速大小为每秒,###米").format(c)); //光速大小为每秒299,792,458米
    }
}

DecimalFormat 类主要靠 # 和 0 两种占位符号来指定数字长度。0 表示如果位数不足则以 0 填充,# 表示只要有可能就把数字拉上这个位置。上面的例子包含了差不多所有的基本用法,如果你想了解更多,请参考 DecimalFormat 类的文档。

 

BigDecimal类

Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数,但在实际应用中,可能需要对更大或者更小的数进行运算和处理。一般情况下,对于那些不需要准确计算精度的数字,我们可以直接使用Float和Double处理,但是Double.valueOf(String) 和Float.valueOf(String)会丢失精度。所以开发中,如果我们需要精确计算的结果,则必须使用BigDecimal类来操作。

​ BigDecimal所创建的是对象,故我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。

常用构造方法

BigDecimal(int)                创建一个具有参数所指定整数值的对象

BigDecimal(double)                创建一个具有参数所指定双精度值的对象             

BigDecimal(long)                创建一个具有参数所指定长整数值的对象

BigDecimal(String)                创建一个具有参数所指定字符串表示的数值的对象

 

对于浮点数,优先使用BigDecimal(String) 构造函数

看下面这个例子

import java.math.BigDecimal;

public class test{
    public static void main(String[] args) {
        //创建两个大整数对象

        BigDecimal v1 = new BigDecimal(0.1);
        BigDecimal v2 = new BigDecimal("0.1");
        System.out.println(v1);
        System.out.println(v2);
    }

}

结果为

原因分析:

1)参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。

2)String 构造方法是完全可预知的:写入 newBigDecimal(“0.1”) 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言, 通常建议优先使用String构造方法。

 

常用方法

  1. add(BigDecimal)

    BigDecimal对象中的值相加,返回BigDecimal对象

  2. subtract(BigDecimal)

    BigDecimal对象中的值相减,返回BigDecimal对象

  3. multiply(BigDecimal)

    BigDecimal对象中的值相乘,返回BigDecimal对象

  4. divide(BigDecimal)

    BigDecimal对象中的值相除,返回BigDecimal对象

  5. toString()

    将BigDecimal对象中的值转换成字符串

  6. doubleValue()

    将BigDecimal对象中的值转换成双精度数

  7. floatValue()

    将BigDecimal对象中的值转换成单精度数

  8. longValue()

    将BigDecimal对象中的值转换成长整数

  9. intValue()

    将BigDecimal对象中的值转换成整数

BigDecimal大小比较

不能使用简单的> < = 来判断,而是要用compareTo方法去判断

 

BigDecimal常见异常

通过BigDecimal的divide方法进行除法时当不整除,出现无限循环小数时,就会抛异常:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

解决方法:

​ divide方法设置精确的小数点,如:divide(xxxxx,2)

 

随机数

使用Random类创建随机数

import java.util.Random;

public class test{
    public static void main(String[] args) {
        Random r  = new Random();
        //随机产生一个int类型取值范围内的数字
        int num1 = r.nextInt();
        System.out.println(num1);

        //创建一个[0~101)的随机数
        int num2 = r.nextInt(101);
        System.out.println(num2);
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值