常用类-包装类,String等

目录

包装类

分析valueOf()

String

可变字符串StringBuffer StringBuilder

Date 日期

Math

枚举类eumn



包装类

就是基本类型的包装类

直接上代码吧。

package com.mark.java.common;

import javax.persistence.criteria.CriteriaBuilder;

public class IntegerDemo {

    public static void main(String[] args) {

        //正常情况
        int a = 10;//基本类型定义
        Integer a1 = new Integer(10);//包装类定义

        //进行了自动装箱,相当于 Integer b = Integer.valueOf(10); 把int类型转为Integer类型
        Integer b = 10;
        //进行了自动拆箱,相当于 int b1 = new Integer(10).intValue(); 把Integer类型转为int类型
        int b1 = new Integer(10);

        //在这里不得不提到比较值  ==,看到等于我们应该想到是 对于引用变量来说是比较两个地址。对于基本类型来说就是比较值。

        //情况1
        int c = 10;
        int c1 = 10;
        c1 =20;
        //当int c=10;时,会在栈中存储一个10,c指向10;如果c1=10;则c1直接指向10;所以c==c1 为true。
        //虽然都指向10,但是如果此时 我们另 c1 = 20;,此时c的值并不会变化,还是指向10,只是在栈中在存储一个20,同时c1 指向 20,此时c ==c1为false
        System.out.println(c==c1); //true ,基本类型,直接比较值



        //情况2
        Integer d = new Integer(10);
        Integer d1 = new Integer(10);
        System.out.println(d == d1); //false ,引用类型,比较地址。

        //情况3
        Integer e = new Integer(10);
        int e1 = 10;
        //true,包装类和基本类型比较是,包装类会自动拆箱,int e2 = new Integer(10).intValue(); 在转换就是int e2 = 10;所以 e2==e1 为true
        System.out.println(e==e1);//true

        //情况4
        Integer f = 100;
        Integer f1 = 100;
        System.out.println(f==f1);//true;
        //这里其实需要自动装箱,变为
        Integer f2 = Integer.valueOf(100);
        Integer f3 = Integer.valueOf(100);
        //要判断f2 == f3 到底是什么,先不要急,我们需要先看一下valueOf()方法是怎么实现的
        //我们可以看到,是由一个if判断的,当满足if条件的时候,是从一个Integer数组中取出来的Integer对象,对于下标是100,取的对象都是同一个,所以f2 ==f3为ture
        System.out.println(f2==f3);//true

        System.out.println("---------------------------");
       //如果上述值变成 200;会怎么样呢
        Integer g = 200;
        Integer g1 = 200;
        System.out.println(g==g1);
        //这里其实需要自动装箱,变为
        Integer g2 = Integer.valueOf(200);
        Integer g3 = Integer.valueOf(200);
        System.out.println(g2==g3);
        //揭晓谜底,当值变为200的时候,就不满足if条件,而是new Integer()对象,所以
        //相当于
        Integer g4 = new Integer(200);
        Integer g5 = new Integer(200);
        System.out.println(g4==g5);
        //这就明确了吧,g4 == g5 一定为false



    }

 }

分析valueOf()

这里我们可以稍微分析下valueOf()方法

1. 可以看到是有个if判断,当满足if条件,从IntegerCache类中的cache数组中取值并返回。

2. 此时我看一下IntegerCathe类,该类是Integer类的静态内部类,该静态内部类在启动的时候在staitc块中就已经创建一个Integer的数据组cache,里面已经创建好了256个Integer对象,是从-127到128的。

3.所以 Integer.valueOf(100)的值是从数组中取的对象,所以f==f1为true。但是当值为200的时候,就会不在这个区间内,而是每次都new Integer(),所以g==g1 为false。

 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() {}
    }

 

String

趁热打铁,我们也可以研究一下String 类型的== 关系。

String有点特殊,所以String是一个引用变量,但是也有两个方法创建对象

  •  String str = "abc"; 

1. 先在常量池中查找是否有“abc"

2. 如果没有,则在常量池中创建”abc“对象,并让str引用该对象

3. 如果有,则直接str指向该对象。

 

  • 2. String str1 = new String("abc");

这种方式一次可能创建两个对象或者一个对象,为什么这么说呢

首先 ”abc“就是一个对象,然后在new String()所以相当于创建了两个对象。

1. 在堆中new String()对象,并让栈中的引用变量str1指向该对象。

2. 在字符串常量池中查找”abc“,如果没有查询到,则在常量池中创建一个对象”abc“,并让堆中的new String()对象指向池中的”abc“

3 .如果查询到常量池中有”abc“对象,则不在创建对象,而是让new String() 对象直接指向池中的”abc“

这里不得不提一下

  • 在JDK1.6及之前版本,字符串常量池在方法区中
  • 在JDK1.7及以后版本,字符串常量池移到了堆中

4. 根据以上,现在可以理解为,栈中str1指向堆中的new String("abc"), 而new String("abc")指向常量池中的”abc“,但是让str1调用一个intern()方法,该方法会把指向常量池”abc“的地址返回。

例如

        String c = "abc";
        String c1 = new String("abc");
        System.out.println(c==c1);//false
        c1 = c1.intern();
        System.out.println(c==c1);//true

5.  ”abc“ 在类加载的时候,就已经创建了一个对象,并存储在字符串常量池中。此时,这个对象的属性已经初始化。"abc"在编译时就被写入字节码中,所以class被加载时,JVM就为"abc"在常量池中 分配内存,创建了对象

所以当 String str = new String("abc") 时,实际上“abc”就已经是一个对象了,可以调用任何String 类的方法。

 

根据以上的介绍,如果要比较两个字符串是否 ==,看下几种场景

package com.mark.java.common;

public class StringDemo {

    public static void main(String[] args) {

        //情况1
        String  a = "abc";
        String  a1 = "abc";
        //a 和 a1都指向常量池中的"abc"
        System.out.println(a==a1);//true

        //情况2
        String b = new String("abc");
        String b1 = new String("abc");
        //b 和 b1 分别指向堆中不同的对象
        System.out.println(b==b1);//false

        //情况3
        String c = "abc";
        String c1 = new String("abc");
        //c 指向常量池中的"abc",而c1执行堆中的 对象
        System.out.println(c==c1);//false
        //调用intern方法,c1指向 将常量池中的"abc",c也指向池中的"abc",所以c1 ==c
        c1 = c1.intern();
        System.out.println(c==c1);//true
        System.out.println("-----------------------------------------");



        //情况4,Stirng 中出现 + 的情况
        String d = "abc";
        String d1 = "efg";
        String d2 = "abcefg";
        String d3 = "abc"+"efg";
        String d4 = d+d1;
        //对于d3,直接去池中找abcefg,所以d2和 d3 指向的时一致的,所以相等
        System.out.println(d2==d3);//true
        
        //对于d4,是 d+d1,是引用变量的相加,是地址的相加,不是值得相加
        //其实在内部会创建一个StringBuilder的对象
        System.out.println(d2==d4);//false
        //相当于
        StringBuilder stringBuilder = new StringBuilder().append(d).append(d1);
        String s = stringBuilder.toString();
        //而下面是StringBuilder的toString方法,就是new String()创建了一个新对象。所以为false
        //public String toString() {
        //        // Create a copy, don't share the array
        //        return new String(value, 0, count);
        //    }


    }
}

 

String 是一个不可变对象,值得属性不可变,但是String里面的属性是 char[] 数组,指的是数组的指向地址不可变,但数据中的内容是可变的。

 String str = "abc";
 相当于: 

     char data[] = {'a', 'b', 'c'};
     String str = new String(data);

也就是说,其实String就是由char数据构成的。String中的属性private final char value[]; 就是这些char数据。

所以String 的 equals 比较的实际上是 两个char数组,比较数据中每一个值是否相等。

String 的常用方法:

1. 构造方法,

String()

String(byte[]) 以及 String(byte[]  ....)

String(char[]) 以及 String(char[] ....)

String(int [] ......)

String(String)

String(StringBuilder)

String(StringBuffer)

2. 成员方法

  • char charAt(int index)  返回 char指定索引处的值。  
  • int compareTo(String anotherString) 按字典顺序比较两个字符串。按照unicode值比较,如果该String对象在参数String之前,返回负整数,之后,返回正整数,相等返回0
  • String concat(String str) 将指定的字符串连接到该字符串的末尾。
  • boolean contains(CharSequence s) 是否包含
  • boolean contentEquals(StringBuffer sb) ,具有指定相同的序列
  • static String copyValueOf(char[] data) 相当于 valueOf(char[]) 。将char数组转成String
  • boolean endsWith(String suffix) 测试此字符串是否以指定的后缀结尾。
  • boolean equals(Object anObject) 
  • boolean equalsIgnoreCase(String anotherString) 忽略大小写的 equals
  • static String format(String format, Object... args)  使用指定格式的字符串,用到占位符
  • byte[] getBytes()  String 转 byte数组
  • void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)  将字符串中的字符复制到char数组中,
  • int hashCode() 返回该字符串的哈希码
  • int indexOf(int ch)  返回指定字符在该字符串中的索引
  • String intern() ,返回该字符串的规范表示
  • boolean isEmpty() 判断字符串lenth是否0
  • static String join(CharSequence delimiter, CharSequence... elements) 
   String message = String.join("-", "Java", "is", "cool");
     // message returned is: "Java-is-cool"
  • static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements)  
List<String> list = new ArrayList<>();
        list.add("我是");
        list.add("一只");
        list.add("可爱的");
        list.add("小猫");
        System.out.println(String.join("--",list));

//返回我是--一只--可爱的--小猫
  • int lastIndexOf(int ch) 返回指定字符 最后一次出现在字符串中的 索引位置
  • int length() ,返回字符串长度
  • boolean matches(String regex)  匹配正则
  • replace replaceAll replaceFirst 替换
  • split  分割
  • startWith 以   开始
  • subString 截取子字符串
  • char[] toCharArray()  转换成char数组
  • String toLowerCase()  转成小写
  • String toUpperCase() 转成大写
  • String trim() ,删除前后空格
  • String valueOf() 转成String类型

 

可变字符串StringBuffer StringBuilder

两者的api基本都相同,不同的是一个是线程安全的,一个是线程不安全的的。

StringBuffer 线程安全的,在成员方法中增加了synchronized,同步锁。由于是可变字符串,所以就存在同时操作一个字符串的问题,所以要加一个锁保证数据同步。

StringBuilder 线程不安全的

参考:https://www.cnblogs.com/xiohao/p/4296088.html

 

Date 日期

相关的类

 

Calendar 日历类,是一个抽象类,抽象类是不能new 对象的。提供一个getInstance方法类获取Calendar对象

Date   sql.Date 是 util.Date的子类。

DateFormat 用来格式化时间

 

 

Math

  • 基本数字运算的方法,加减乘除,平方,开平方 ,三角函数,

  • 获取随机数Math.random()
package com.mark.java.common;

public class MathDemo {
    public static void main(String[] args) {
        System.out.println(Math.random());
        //向上取整
        System.out.println(Math.ceil(3.14));
        //向下取整
        System.out.println(Math.floor(3.14));
        //四舍五入
        System.out.println(Math.round(3.14));

    }
}

枚举类eumn

1.  用enum修饰

2. 枚举类中的枚举值相当于枚举类的对象,且是用 public static final修饰,可以直接用类调用。

3. 枚举类有属性,构造方法,普通方法等

4. 枚举类可以当做常量类来使用。直接获取A的value值。作为常量。

 String code = EnumDemo2.A.getValue();

 

无参构造

package com.mark.java.common;

import sun.security.util.ECUtil;

public enum EnumDemo {
    //可以当成是EnumDemo类的两个实例化对象
    //相当于acct(),client();,调用的时无参数的构造方法;
    acct,client;

    EnumDemo(){

    }
    

}

 

有参数构造

package com.mark.java.common;

public enum  EnumDemo2 {

    //枚举,可以当成该枚举类的实例对象。
    //相当于public static final 修饰,直接用类名进行调用
    A("01","哈哈"),
    B("02","呵呵");

    //属性
    private String code;
    private String value;

    //构造方法
    private EnumDemo2(String code,String value){
        this.code=code;
        this.value=value;
    }

    //get set 方法
    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    //普通方法
    //提供了values方法,能将枚举类中的枚举值转成数组。
    public static void show(){
        EnumDemo2[] values = EnumDemo2.values();
        for (EnumDemo2 enumDemo2 : values) {
            System.out.println(enumDemo2.name());
        }
    }
    //根据code获取value值
    public static String getValueByCode(String code){

        EnumDemo2[] values = EnumDemo2.values();
        for (EnumDemo2 enumDemo2 : values) {
            if(enumDemo2.getCode().equals(code)){
                return enumDemo2.getValue();
            }
        }
        return null;
    }
}

class A{
    public static void main(String[] args) {
        EnumDemo2.show();
        System.out.println(EnumDemo2.A.getCode()+":"+EnumDemo2.A.getValue());

        String valueByCode = EnumDemo2.getValueByCode("01");
        System.out.println(valueByCode);
    }
}

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值