尚学堂视频笔记四:常用类

常用类

1. 包装类

1.1 包装类基本知识

​ java是面向对象的语言,但并不是"单纯面向对象"的,因为我们经常用到的基本数据类型就不是对象。但是我们在实际应用中经常需要将基本数据类型转化成对象,以便于操作。比如:将基本数据类型存储到Object[]数据或集合中的操作等等。

​ 为了解决这个不足,Java在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本类型对应的类统称为包装类(Wrapper Class)。

​ 基本数据类型对应的包装类

基本数据类型包装类
byteByte
booleanBoolean
shortShort
charCharacter
intInteger
longLong
floatFloat
doubleDouble

​ 在这八个类名中,除了Integer和Character类意外,其他六个类的类名和基本数据类型一致,只是类名的第一个字母大写而已。

​ 在这八个类中,除类Character和Boolean以外,其他的都是"数字型","数字型"都是java.lang.Number的子类。Number类是抽象类,因此它的抽象方法,所有子类都需要提供实现、Number类提供了抽象方法:intValue()、longValue()、floatValue()、doubleValue(),意味着所有的"数字型"包装类都可以相互转型。

​ 下面是一个包装类的例子:

package com.helloworld;

public class TestWrapperClass {

    public static void main(String[] args) {
        // 基本数据类型转成包装类对象
        Integer a = new Integer(3);
        Integer b = Integer.valueOf(30);// 一般建议采用这种方式

        // 把包装类转成基本数据类型
        int c = b.intValue();
        double d = b.doubleValue();


        // 将字符串转化成包装类对象
        Integer e = new Integer("9999");
        Integer f = Integer.parseInt("10101001", 2);
        System.out.println(f + " ");

        // 把包装类转化成字符串
        String str = f.toString();

        // 常见的常量
        System.out.println("int类型最大的整数: " + Integer.MAX_VALUE);

    }

}

1.2 自动装箱和拆箱

​ 自动拆箱和拆箱就是把基本数据类型和包装类之间进行自动的相互转化。JDK1.5后,Java引入了自动装箱(autoboxing)和拆箱(unboxing)

自动装箱:

​ 基本数据类型的数据处于需要对象的环境中时,会自动转化为"对象"。

自动拆箱:

​ 每当需要一个值时,对象会自动转成基本数据类型,没必要在去显示调用intValue()、doubleValue()等转型方法。

​ 自动装过程是通过调用包装类的valueOf()方法实现的,而自动拆箱过程是通过调用包装类的xxxValueOf()方法实现的(xxx代表对应的基本数据类型,如intValue()、doubleValue()等)。

1.3 String类

​ String类对象代表不可变类的Unicode字符序列,因此String对象成为不可变对象。

​ 在String类中:

public final class String
	implements java.io.Serializable, Comparable<String>, CharSequence {
		private final char value[];
	}

核心就是 private final char value[]。由于存在final修饰,所以String对象只能在初始化时赋值一次,这也是String对象不可变的原因。

​ 在遇到字符串常量之间的拼接时,编译器会做出优化,即在编译期间就会完成字符串的拼接。因此,在使用 == 进行String对象之间的比较时,我们需要特别注意:

package CommonClass;

public class StringTest {

    public static void main(String[] args) {

        // 编译器做了优化,直接在编译的时候将字符串进行拼接
        String str1 = "hello" + "java";//相当于hellojava
        String str2 = "hellojava";
        System.out.println(str1 == str2);

        String str3 = "hello";
        String str4 = "java";
        String str5 = str3 + str4;
        // 编译时不知道变量中存储的是什么,所以没有办法在编译时进行优化。
        System.out.println(str2 == str5);
    }
}

/**
*true
*false
*/

StringBuiler类

​ StringBuilder源码中:

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    char[] value;
    int count;
    AbstractStringBuilder(){
        
    }
}

char[] value 并没有使用final进行修饰,这意味着,StringBuilder类创建的对象,可以进行修改

package CommonClass;

public class StringBuilderClass {

    public static void main(String[] args) {
        String str;

        //StringBuilder线程不安全,效率高;StringBuffer线程安全,但是效率低,一般使用StringBuilder类
        StringBuilder sb = new StringBuilder("absgcesf");
        System.out.println(Integer.toHexString(sb.hashCode()));

        System.out.println(sb);


        sb.setCharAt(2, 'M');
        sb.setCharAt(5, 'C');
        System.out.println(Integer.toHexString(sb.hashCode()));
        System.out.println(sb);
    }

}

常用方法:
StringBuilder.reverse();// 倒序
StringBuilder.setCharAt(int index, char str);// 将指定位置修改字符
StringBuilder.insert(int offset, char c);// 在指定位置插入, 由于返回的是自身,所以可以链式调用
StringBuilder.delete(int start, int end);// 删除指定区间。同时返回自身,可以进行链式调用

不可变和可变字符串的陷阱:

​ 使用StringBuilder进行字符串的拼接,如果使用for循环进行拼接,就会产生大量的内存和时间的浪费。

​ 所以使用SringBuilder.append()方法来循环累加字符串,又节省空间,又节省时间。

1.4 时间处理相关类:

​ 在计算机的世界里面,我们把1970年1月1日 00:00:00 定位基准时间,每个度量单位是毫秒

​ 我们用long类型的变量来表示时间,从基准时间往前几亿年,往后几亿年都能表示。如果想获得现在时刻的"时刻数值",可以使用:

long now = System.currentTimeMillis();

​ 这个"时刻数组"是所有时间类的核心值,年月日都是根据这个"数值"计算出来的。我们工作学习涉及的时间相关类有如下类:

[外链图片转存失败(img-2EshJUqi-1565414323541)(E:\Document\java\JAVE EE\尚学堂笔记\深度截图_选择区域_20190707164931.png)]

常用的方法:

​ 核心-Date.getTime()获得毫秒数

​ 由于Date中的很多方法已经被废弃了(已经被Calendar所取代),所以掌握核心即可。而其中很多和字符串相关的方法,也已经被DateFormat所取代。

1.5 DateFormat和SimpleDateFormat

​ 其中,SimpleDateFormat是DateFormat的实现类,我们在实际运用中一般使用SimpleDateFormat。

  • DateFormat类的作用

    把时间对象转化成指定格式的字符串。反之,把指定格式的字符串转化成事件对象。

    DateFormat是一个抽象类,一般使用它的子类SimpleDateFormat类来实现。

    代码中的格式转化字符的具体含义:

    字母日期或时间元素表示实例
    GEra 标志符TextAD
    yYear1996; 96
    M年中的月份MonthJuly; jul; 07
    w年中的周数Number27
    W月份中的周数Number2
    D年中的天数Number189
    d月份中的天数Number10
    F月份中的星期Number2
    E星期中的天数TextTuesday; Tue
    aAm/pm 标记liziTextPm
    H一天中的小时数(0-23)Number0
    k一天中的小时数(1-24)Number24
    Kam/pm中的小时数(0-11)Number0
    ham/pm中的小时数(1-12)Number12
    m小时中的分钟数Number30
    s分钟中的秒数Number55
    S毫秒数Number978
    z时区General time zonePacific Standard Time; PST; GMT-08:00
    Z时区RFC 822 time zone0800
  • 一些例子

package CommonClass;

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

/**
 * 测试时间对象和字符串之间的相互转化
 */
public class TestDateFormat {

    public static void main(String[] args) throws ParseException {
        // 把时间按照指定格式,转化成字符串
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String str = df.format(new Date());
        System.out.println(str);

        // 把字符串按照响应的格式转化成时间对象
        DateFormat df2 = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
        Date date = df2.parse("1983年5月10日 12:55:30");
        System.out.println(date);
        
        //测试其他的格式字符。比如,利用D,获取现在是当前年的第几天。
        DateFormat df3 = new SimpleDateFormat("D");
        String str3 = df3.format(new Date());
        System.out.println(str3);
    }

}
/**
* 2019-07-07 08:46:12
* Tue May 10 00:55:30 CST 1983
* 188
*/

/*
* 如果抛出了java.text.ParseException: Unparseable date: "****"
* 说明你输入的日期格式错误
*/

1.6 Calendar日期类

​ Calendar类是一个抽象类,为我们提供了关于日期计算的相关功能。比如,年、月、日、时、分、秒的展示和计算。

​ GregorianCalendar是Calendar的一个具体的一个子类,提供了世界上大多数国家/地区使用的标准日历系统。

  • 菜鸟雷区

​ 注意月份的表示,一月是 0 ,二月是1,以此类推,12月是11。因为大多数人习惯于使用单词而不是使用数字来表示月份,这样程序也许更易读,父类Calendar使用常量来表示月份:JANUARY、FEBRUARY等等。

  • 一些示例

package CommonClass;

import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 测试日期类的使用
 */

public class TestCalendar {

    public static void main(String[] args) {


        Calendar calendar = new GregorianCalendar(2999,10,9,22,10,50);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int whichDay = calendar.get(Calendar.DAY_OF_WEEK);
        int day = calendar.get(Calendar.DATE); // 也可以使用DATE_OF_MONTH
        System.out.println(year);
        System.out.println(whichDay);// 星期几 1-7 1-星期日 2-星期一 7-星期日
        System.out.println(month);//0-11表示对应的月份 0-一月份 11-十二月
        System.out.println(day);

        //设置日期的相关元素
        Calendar c = new GregorianCalendar();
        c.set(Calendar.YEAR, 9102);

        System.out.println(c);

        //日期的计算
        Calendar c1 = new GregorianCalendar();
        c1.add(Calendar.DATE, 100);
        System.out.println(c1);

        //日期对象和时间对象的转化
        Date d4 = c1.getTime();
        Calendar c2 = new GregorianCalendar();
        System.out.println(c2);
        c2.setTime(d4);
        System.out.println(d4);
        System.out.println(C2);
    }

    
}
// 结果
/*
2999
7
10
9
java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=9102,MONTH=6,WEEK_OF_YEAR=28,WEEK_OF_MONTH=2,DAY_OF_MONTH=7,DAY_OF_YEAR=188,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=9,HOUR_OF_DAY=21,MINUTE=27,SECOND=23,MILLISECOND=419,ZONE_OFFSET=28800000,DST_OFFSET=0]
java.util.GregorianCalendar[time=1571146043419,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2019,MONTH=9,WEEK_OF_YEAR=42,WEEK_OF_MONTH=3,DAY_OF_MONTH=15,DAY_OF_YEAR=288,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=9,HOUR_OF_DAY=21,MINUTE=27,SECOND=23,MILLISECOND=419,ZONE_OFFSET=28800000,DST_OFFSET=0]
java.util.GregorianCalendar[time=1562506043420,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2019,MONTH=6,WEEK_OF_YEAR=28,WEEK_OF_MONTH=2,DAY_OF_MONTH=7,DAY_OF_YEAR=188,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=9,HOUR_OF_DAY=21,MINUTE=27,SECOND=23,MILLISECOND=420,ZONE_OFFSET=28800000,DST_OFFSET=0]
Tue Oct 15 21:27:23 CST 2019
java.util.GregorianCalendar[time=1571146043419,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2019,MONTH=9,WEEK_OF_YEAR=42,WEEK_OF_MONTH=3,DAY_OF_MONTH=15,DAY_OF_YEAR=288,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=9,HOUR_OF_DAY=21,MINUTE=27,SECOND=23,MILLISECOND=419,ZONE_OFFSET=28800000,DST_OFFSET=0]
*/
  • 简单的可视化日历

package CommonClass;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Scanner;
import java.util.concurrent.CancellationException;

/**
 * 可视化日历程序
 */
public class TestCalendarHomeWork {

    public static void main(String[] args) throws ParseException {
        System.out.println("请输入日期:2020-9-10");
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date date =  df.parse(str);
        Calendar c = new GregorianCalendar();
        c.setTime(date);

        System.out.println("日\t一\t二\t三\t四\t五\t六");

        int today = c.get(Calendar.DAY_OF_MONTH);

        c.set(Calendar.DAY_OF_MONTH, 1);

        for (int i = 0; i < c.get(Calendar.DAY_OF_WEEK) -1; i++) {
            System.out.print("\t");
        }

        int maxDay = c.getActualMaximum(Calendar.DATE);

        for (int i = 0; i < maxDay; i++) {

            if(today == c.get(Calendar.DAY_OF_MONTH)){
                System.out.print(c.get(Calendar.DAY_OF_MONTH) + "*\t");
            }
            else {
                System.out.print(c.get(Calendar.DAY_OF_MONTH) + "\t");
            }
            if(c.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY){
                System.out.println("\t"); //换行操作
            }

            c.add(Calendar.DAY_OF_MONTH, 1);
        }
    }

}

//结果
/*
请输入日期:2020-9-10
2020-9-10
日	一	二	三	四	五	六
		1	2	3	4	5		
6	7	8	9	10*	11	12		
13	14	15	16	17	18	19		
20	21	22	23	24	25	26		
27	28	29	30	
*/

1.7 File类的基本用法

​ java.io.File类:代表文件和目录。在开发中,读取文件、生成文件、删除文件、修改文件的属性时,经常会用到本类。

File类的常见的构造方法:public File(String pathname)

​ 以pathname为路径创建File对象,如果pathname是相对路径,则默认的当前路径在系统属性user.dir中存储。

package CommonClass;

import java.io.File;
import java.io.IOException;
import java.util.Date;

/**
 * 测试File类的基本用法
 */
public class TestFile {

    public static void main(String[] args) throws IOException {

        File f = new File("/home/qianqian/txt.txt");
        System.out.println(f);
        f.renameTo(new File("/home/qianqian/aa.txt"));

        System.out.println(System.getProperty("user.dir"));

        File f2 = new File("gg.txt");
        f2.createNewFile();

        System.out.println("File是否存在: " + f2.exists());
        System.out.println("File是否是目录:" + f2.isDirectory());
        System.out.println("File是否是文件:" + f2.isFile());
        System.out.println("File的大小:" + f2.length());
        System.out.println("File最后的修改时间:" + new Date(f2.lastModified()));
        System.out.println("File的文件名:" + f2.getName());
        System.out.println("File的目录根路径:" + f2.getAbsolutePath());

//        f2.delete();

        File f3 = new File("01/02/03");


        if(f3.exists()) {

        }
            f3.delete();

        File f4 = new File("01/02");
        f4.delete();

        File f5 = new File("01");
        f5.delete();
    }

}

File类-递归打印目录树结构

package CommonClass;

import java.io.File;

/**
 * 使用递归算法打印目录树
 */
public class TestPrintFileTrees {

    public static void main(String[] args) {
        File f = new File("/media/qianqian/新加卷/Document/self-learning");
        printFile(f,0);
    }

    static void printFile(File file, int level) {

        for (int i = 0; i < level; i++) {
            System.out.print("\t");
        }
        System.out.println(file.getName());
        if(file.isDirectory()) {
            File[] files = file.listFiles();
            for(File temp : files) {
                printFile(temp, level + 1);
            }
        }
    }

}

1.8 枚举

​ JDK1.5引入枚举类型。枚举类型的定义包括枚举声明和枚举体。格式如下

enum 枚举名 {
    枚举体 (常量列表)
}

​ 枚举体就是放置一些常量。我们可以写出我们第一个枚举类型。

enum Season {
    SPRING, SUMMER, AUTUMN, WINDER
}

​ 所有的枚举类型隐性地继承自java.lang.Enum。枚举实质上还是类!而每个被枚举的成员实质就是一个枚举类型的实例,他们默认都是 public static final 修饰的。可以直接通过枚举类型名来使用它们。

建议

  1. 当你需要定义一组常量时,可以使用枚举类型。
  2. 尽量不要使用枚举类型的高级特性,事实上高级特性都可以使用普通类来实现,没有必要引入枚举来增加程序的复杂性。
package CommonClass;

/**
 * 测试枚举
 */
public class TestEnum {

    public static void main(String[] args) {
        System.out.println(Season.SPRING);

        Season a = Season.AUTUMN;

        switch (a) {
            case SPRING:
                System.out.println("Now, it's Spring.");
                break;
            case SUMMER:
                System.out.println("Now, it's Summer");
                break;
            case AUTUMN:
                System.out.println("Now, it's Autumn");
                break;
            case WINTER:
                System.out.println("Now, it's Winter");
                break;
        }
    }

}


enum Season {
    SPRING, SUMMER, AUTUMN, WINTER
}

enum Week {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FIRDAY, SATUDAY, SUNDAY
}s
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值