欢迎来到 Kong Xiangqun 的博客

14、常用类

一、基本数据类型的包装类

基本类型4类8中:数值型、浮点型、字符型、布尔型

我们在日常工作中经常会用到集合框架:比如List、Map、Set

本身放值是没问题的,但是在Api里有一些基本的规定

源码:

例如:ArrayList

 

 里面有一个重要的方法add

 

 

 

 E e 表示什么意思

/**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */

看下继承关系,最上面

 

 

 Collection有一个add

 

 里面也有个E e

里面传入的值要是一个Object类型的一个对象

我们之前int、double、float都属于数值,而不是一个类,数值只表示一个单一的值,而类

表示有对应的属性和有对应的一个方法

所以如果没有包装类的话,放1、2、3这些值时可能会存在写问题

因此有了包装类

 1、包装类

包装类是将基本类型封装到一个类中
包含属性和方法,方便对象操作
包装类位于java.lang包中

 

 

public class IntegerDemo {
    public static void main(String[] args) {
        int a = 10;
        Integer i = new Integer(10);
        System.out.println(a == i);
    }
}

打印结果:

/*
true

Process finished with exit code 0
*/
/*
* 包装类与基本数据类型
*   包装类是将基本数据类型封装成一个类,包含属性和方法
*   使用:
*       在使用过程中,会涉及到自动装箱和自动拆箱
*       装箱:将基本数据类型转换成包装类
*       拆箱:将包装类转换成基本数据类型
*
* */

源码:

 

 2、相互转换

public class IntegerDemo {
    public static void main(String[] args) {
        int a = 10;
        Integer i = new Integer(10);
        //通过方法进行类型的转换
        Integer i2 = Integer.valueOf(a);
        int i3 = i.intValue();
        System.out.println(a == i);
    }
}

源码:

 返回值是一个Integer对象

 返回的是值

3、Float、Double等等

public class IntegerDemo {
    public static void main(String[] args) {
        Float f1 = new Float(3.14);
        Double d1 = new Double(3.14);
    }
}

4、面试题:

4.1

public class IntegerDemo {
    public static void main(String[] args) {
        Integer i1 = 100;
        Integer i2 = 100;
        Integer i3 = 200;
        Integer i4 = 200;
        System.out.println(i1==i2);
        System.out.println(i3==i4);
    }
}

打印结果:

/*
true
false

Process finished with exit code 0
*/

原因:

/*
int i = 100;
Integer i1 = 100;
这两个是完全不一样的
上面的是简单的赋值
下面的完成了两个步骤,
先定义100,再转换为Integer类型,Integer.vauleOf(100)
*/

 

/*
i是100,100>-128 && 100 <=127
返回的是Integer 对象, 只不过是cache规定好的数组
i2=100, 同样也返回的是数组里指定的

i3=200, 不在
i4=200, 不在
意味着每次都要new 一个Integer, 对象地址就不一样了
*/

4.2

public class IntegerDemo {
    public static void main(String[] args) {
        Double d1 = 1.0;
        Double d2 = 1.0;
        Double d3 = 2.0;
        Double d4 = 2.0;
        System.out.println(d1==d2);
        System.out.println(d3==d4);
    }
}

打印结果:

/*
false
false

Process finished with exit code 0
*/

原因:

/*
每次都是一个新的new
所以为false
*/

4.3、

public class IntegerDemo {
    public static void main(String[] args) {
        Integer i = 10;
        int a = i;
        System.out.println(a==i);
    }
}

打印结果:

/*
true

Process finished with exit code 0
*/

原因:

/*
会自动拆箱
*/

 

二、字符串相关类

public class StringDemo {
    public static void main(String[] args) {
        String str = "abc";
        String str2 = new String("abc");
    }
}

"abc"是放到什么地方的?

/*
常量池,
常量池在1.7之后放置在了堆空间之中,不是在方法区
*/
public class StringDemo {
    public static void main(String[] args) {
        String str = "abc";
        String str2 = new String("abc");
        System.out.println(str==str2);
        System.out.println(str.equals(str2));
    }
}

结果为:

/*
false
true Process finished with exit code 0
*/

再看

public class StringDemo {
    public static void main(String[] args) {
        String str = "abc";
        String str2 = new String("abc");
        str2 = str2.intern();
        System.out.println(str==str2);
        System.out.println(str.equals(str2));
    }
}

结果为:

/*
true
true

Process finished with exit code 0
*/

就变成true了

 

1、字符串的本质

1.1、字符串的本质是字符数组或者叫做字符序列

1.2、String类使用final修饰,不可以被继承

1.3使用equals方法比较的是字符数组的每一个位置的值

 

 

1.4、hashCode()

 

 

 为什么用31乘

/*
31的二进制是 11111
16+8+4+2+1
移位运算速度是最快的
*/

1.5、其他方法

public class StringDemo {
    public static void main(String[] args) {
        String str = "abc";
        String str2 = new String("abc");
        str2 = str2.intern();
        System.out.println(str==str2);
        System.out.println(str.equals(str2));
        //返回下标对应的值
        System.out.println(str.charAt(0));
        //数组的复制过程 拼接
        System.out.println(str.concat("cde"));
        //返回指定下标的元素
        System.out.println(str.indexOf("a"));
        String s = "abcdefghijklmn";
        System.out.println(s.substring(3));
        //在截取字符串的时候,需要注意是左闭右开区间
        System.out.println(s.substring(3,5));
        System.out.println(s.length());
    }
}

打印结果:

/*
true
true
a
abccde
0
defghijklmn
de
14
*/

常用方法总结:

char charAt(int index)
//返回字符串中第index个字符。
boolean equals(String other)
//如果字符串与other相等,返回true
boolean equalsIgnoreCase(String other) 
//如果字符串与other相等(忽略大小写),则返回true 
int indexOf(String str) lastIndexOf(String str,int idx)  int length()
//返回字符串的长度。
String replace(char oldChar,char newChar)
//返回一个新串,它是通过用 newChar 替换此字符串中出现的所有oldChar
而生成的
boolean startsWith(String prefix)
//如果字符串以prefix开始,则返回true
boolean endsWith(String prefix) 
//如果字符串以prefix结尾,则返回true
String substring(int beginIndex) 
String substring(int beginIndex,int endIndex) //返回一个新字符串,该串包含从原始字符串beginIndex到串尾戒endIndex-1的所有字符 String toLowerCase() //返回一个新字符串,该串将原始字符串中的所有大写字母改成小写字母 String toUpperCase() //返回一个新字符串,该串将原始字符串中的所有小写字母改成大写字母 String trim() //返回一个新字符串,该串删除了原始字符串头部和尾部的空格

 

回到上面的一个问题,调用intern()方法后,为什么a==b就是true了

public class StringDemo {
    public static void main(String[] args) {
        String a = "abc";
        String b = new String("abc");
        b = b.intern();
        System.out.println(a==b);
    }
}

打印结果为:

/*
true

Process finished with exit code 0
*/

 

 

 当方法被调用是, 如果常量池已经包含了一个string, 并且equal 等于这个string对象时,池子里面这个string将会被return

一个字符串池,最初是空的,由类私下维护String。
当调用 intern 方法时,如果池中已经包含一个与String该方法确定的对象相等equals(Object)的字符串,则返回池中的字符串。否则,将此String对象添加到池中并String返回对该对象的引用。
由此可见,对于任何两个字符串s和t, 当且 仅当s.intern() == t.intern()是。 trues.equals(t)true
所有文字字符串和字符串值的常量表达式都是实习的。字符串文字在 The Java™ Language Specification的第 3.10.5 节中定义。
回报:
与此字符串具有相同内容的字符串,但保证来自唯一字符串池。

 

 

 

对象地址和

 

地址比较肯定有问题的所以是false

当用intern方法后, 

如果池中已经包含一个与String该方法确定的对象相等equals(Object)的字符串,则返回池中的字符串

 

 所以a==b 了,返回true

 

public class StringDemo {
    public static void main(String[] args) {
        String a = "abc";
        String b = "def";
        String c = "abcdef";
        String d = a+b;
        String d1 = (a+b).intern();
        String e = "abc"+"def";
        System.out.println(c==d);
        System.out.println(c==d1);
        System.out.println(c==e);
    }
}

打印结果为:

/*
false
true
true

Process finished with exit code 0
*/
public class StringDemo {
    public static void main(String[] args) {
        String f = "a" + "b" +"c";
        String a1 = "a";
        String a2 = "b";
        String a3 = "c";
        String f1 = a1+a2+a3;
    }
}

这个创建了几个对象?

f是 1 个对象

f1是 4 个对象

1.6、String是一个不可变对象

指的是数组的引用关系是不可以变的, 值是能改变的

2、可变字符序列:StringBuffer、StringBuilder

public class StringBufferDemo {
    public static void main(String[] args) {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(1).append(1.234).append("abc").append(true);
        System.out.println(stringBuffer);
        System.out.println(stringBuffer.length());
        System.out.println(stringBuffer.capacity());
StringBuilder stringBuilder
= new StringBuilder(); stringBuilder.append("123").append(1).append(false); System.out.println(stringBuilder); } }

打印结果为:

11.234abctrue
13 // length() 表示 字符串放置在数组里占用数组的大小
16 // 初始化时的容量是16
1231false

线程安全

StringBuffer都是用synchronized修饰的(同步加锁), 是线程安全的

StringBuilder是线程不安全的

/*
* 可变字符串
*   StringBuffer:线程安全,效率低
*   StringBuilder: 线程不安全,效率高
* */

三、时间处理相关类

1、Date

DateFormat、SimpleDateFormat

Calender

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

public class DateDemo {
    public static void main(String[] args) throws ParseException {
        Date date = new Date();
        System.out.println(date);
        System.out.println(date.getTime());
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //将Date类按照规范转换为字符串格式
        String str = dateFormat.format(date);
        System.out.println(str);
        //将字符串转换成对应的日期类
        Date d1 = dateFormat.parse("2010-10-10 20:20:20");
        System.out.println(d1);

        //获取的是当前系统的时间
        Calendar calendar = Calendar.getInstance();
        System.out.println(calendar);
        //设置指定时间的日历类
        calendar.setTime(d1);
        System.out.println(calendar);
        System.out.println(calendar.get(Calendar.YEAR));
        System.out.println(calendar.get(Calendar.MONTH));
        System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
        System.out.println(calendar.get(Calendar.HOUR_OF_DAY));
        System.out.println(calendar.get(Calendar.MINUTE));
        System.out.println(calendar.get(Calendar.SECOND));

    }
}

打印结果为:

/*
Sun Apr 17 19:42:12 CST 2022
1650195732274
2022-04-17 19:42:12
Sun Oct 10 20:20:20 CST 2010
java.util.GregorianCalendar[time=1650195732403,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2022,MONTH=3,WEEK_OF_YEAR=17,WEEK_OF_MONTH=4,DAY_OF_MONTH=17,DAY_OF_YEAR=107,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=7,HOUR_OF_DAY=19,MINUTE=42,SECOND=12,MILLISECOND=403,ZONE_OFFSET=28800000,DST_OFFSET=0]
java.util.GregorianCalendar[time=1286713220000,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2010,MONTH=9,WEEK_OF_YEAR=42,WEEK_OF_MONTH=3,DAY_OF_MONTH=10,DAY_OF_YEAR=283,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=8,HOUR_OF_DAY=20,MINUTE=20,SECOND=20,MILLISECOND=0,ZONE_OFFSET=28800000,DST_OFFSET=0]
2010
9
10
20
20
20

Process finished with exit code 0
*/

四、Math类

public class MathDemo {
    public static void main(String[] args) {
        System.out.println(Math.abs(-1));
        System.out.println(Math.sqrt(2));
        System.out.println(Math.ceil(-3.14)); //向上取整
        System.out.println(Math.floor(-3.14)); //向下取整
        System.out.println(Math.pow(2,3));

    }
}

打印结果为:

/*
1
1.4142135623730951
-3.0
-4.0
8.0
*/

五、枚举类:Jdk1.5

public enum Gender {
    男,女
}
public class Test {
    Gender gender = Gender.女;
    Gender gender2 = Gender.男;
    }
}

这种方式就太low了

定义一个Enum

public enum EventEnum {

    LAUNCH("launch"),PAGEVIEW("pageview"),EVENT("event");

    EventEnum(String name){
        this.name = name;
    }
    private String name;

    public void show(){
        System.out.println(this.name);
        EventEnum[] ee = values();
        for(int i = 0;i<ee.length;i++){
            System.out.println(ee[i]);
        }
    }

}
public class Test {
    Gender gender = Gender.女;
    Gender gender2 = Gender.男;

    public static void main(String[] args) {
        EventEnum ee = EventEnum.LAUNCH;
        ee.show();
        String name = EventEnum.PAGEVIEW.name();
        System.out.println(name);
    }
}

打印结果为:

/*
launch
LAUNCH
PAGEVIEW
EVENT
PAGEVIEW

Process finished with exit code 0
*/
枚举类型:
  • 1. 只能够取特定值中的一个
  • 2. 使用enum关键字
  • 3. 所有的枚举类型隐性地继承自 java.lang.Enum。(枚举实质上还是类!
  •     而每个被枚举的成员实质就是一个枚举类型的实例,他们默认都是public static final的。
  •     可以直接通过枚举类型名直接使用它们。)
  • 4. 强烈建议当你需要定义一组常量时,使用枚举类型

 

六、File类

后面再说

 

posted @ 2022-04-25 21:15  kongxiangqun20220317  阅读(31)  评论(0编辑  收藏  举报