天天看点

Java常用类——第二部分

上一篇:Java常用类——第一部分

9.3 JDK8中新日期时间API

1. 新日期时间API出现的背景

JDK 1.0中包含了 一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用了。而Calendar并不比Date好多少。它们面临的问题是:

  • 可变性:像日期和时间这样的类应该是不可变的。
  • 偏移性:Date中的年份是从1900开始的,而月份都从0开始。
  • 格式化:格式化只对Date有用,Calendar则不行。
  • 此外,它们也不是线程安全的;不能处理闰秒等。

第三次引入的API是成功的,并且Java 8中引入的java.time API 已经纠正了过去的缺陷。

Java 8 吸收了 Joda-Time 的精华,以一个新的开始为 Java 创建优秀的API。 新的 java.time 中包含了所有关于 本地日期(LocalDate)、本地时间 (LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime)和持续时间(Duration) 的类。历史悠久的 Date 类新增了 toInstant() 方法,用于把 Date 转换成新的表示形式。这些新增的本地化时间日期 API 大大简化了日期时间和本地化的管理。

2. 新时间日期API
  • java.time – 包含值对象的基础包(常用)
  • java.time.chrono – 提供对不同的日历系统的访问
  • java.time.format – 格式化和解析时间和日期(常用)
  • java.time.temporal – 包括底层框架和扩展特性(偶尔用)
  • java.time.zone – 包含时区支持的类
3. LocalDate、LocalTime、LocalDateTime类

LocalDate、LocalTime、LocalDateTime 类是新API中较重要的几个类,它们的实例是不可变的对象,分别表示使用 ISO-8601日历系统(ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法,也就是公历。)的日期、时间、日期和时间。它们提供了简单的本地日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。

  • LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存储生日、纪念日等日期。
  • LocalTime表示一个时间,而不是日期。
  • LocalDateTime是用来表示日期和时间的,这是一个最常用的类之一。

说明

  • LocalDateTime相较于LocalDate、LocalTime,使用频率要高
  • 类似于Calendar

相关方法

方法 描述
now() / * now(ZoneId zone) 静态方法,根据当前时间创建对象 / 指定时区的对象
of() 静态方法,根据指定日期 / 时间创建对象(没有偏移量)
getDayOfMonth() / getDayOfYear() 获得月份天数(1-31) / 获得年份天数(1-366)
getDayOfWeek() 获得星期几,返回一个 DayOfWeek 枚举值
getMonth() 获得月份,返回一个 Month 枚举值
getMonthValue() / getYear() 获得月份(1-12) / 获得年份
getHour() / getMinute() / getSecond() 获得当前对象对应的小时、分钟、秒
withDayOfMonth() / withDayOfYear() / withMonth() / withYear() 将月份天数、年份天数、月份、年份修改为指定的值并返回新的对象
plusDays() / plusWeeks() / plusMonths() / plusYears() / plusHours() 向当前对象添加几天、几周、几个月、几年、几小时
minusMonths() / minusWeeks() / minusDays() / minusYears() / minusHours() 从当前对象减去几月、几周、几天、几年、几小时
4. 瞬时:Instant类

Instant:时间线上的一个瞬时点;这可被用来记录应用程序中的事件时间戳,它类似于java.util.Date类

java.time包通过值类型Instant提供机器视图,不提供处理人类意义上的时间单位。 Instant表示时间线上的一点,而不需要任何上下文信息,例如,时区。 概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC)开始的秒数。 因为java.time包是基于纳秒计算的,所以Instant的精度可以达到纳秒级。

相关方法

方法 描述
now() 静态方法,返回默认UTC时区的Instant类的对象
ofEpochMilli(long epochMilli) 静态方法,返回在1970-01-01 00:00:00基础上加上指定毫秒数之后的Instant类的对象
atOffset(ZoneOffset offset) 结合即时的偏移来创建一个OffsetDateTime
toEpochMilli() 返回1970-01-01 00:00:00到当前时间的毫秒数,即为时间戳(时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。)
5. 格式化与解析日期或时间

格式化与解析日期或时间使用java.time.format.DateTimeFormatter类,类似于SimpleDateFormat;该类提供了三种格式化方法:

  • 预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
  • 本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG)
    • FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT:适用于LocalDateTime
    • FormatStyle.FULL / FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT1:适用于LocalDate
  • 自定义的格式。如:ofPattern(“yyyy-MM-dd HH:mm:ss”)

相关方法

方法 描述
ofPattern(String pattern) 静态方法,返回一个指定字符串格式的DateTimeFormatter
format(TemporalAccessor t) 格式化一个日期、时间,返回字符串
parse(CharSequence text) 将指定格式的字符序列解析为一个日期、时间
6. 其它API
  • ZoneId:该类中包含了所有的时区信息,一个时区的ID,如 Europe/Paris
  • ZonedDateTime:一个在ISO-8601日历系统时区的日期时间,如 2007-12-03T10:15:30+01:00 Europe/Paris;其中每个时区都对应着ID,地区ID都为“{区域}/{城市}”的格式,例如:Asia/Shanghai等
  • Clock:使用时区提供对当前即时、日期和时间的访问的时钟。
  • 持续时间:Duration,用于计算两个“时间”间隔,以秒和纳秒为基准
  • 日期间隔:Period,用于计算两个“日期”间隔,以年、月、日衡量
  • TemporalAdjuster:时间校正器。有时需要获取例如:将日期调整到“下一个工作日”等操作。
  • TemporalAdjusters:该类通过静态方法 (firstDayOfXxx() / lastDayOfXxx() / nextXxx())提供了大量的常用 TemporalAdjuster的实现。
7. 新API与传统日期处理的转换
To 遗留类 From 遗留类
java.time.Instant与java.util.Date Date.from(instant) date.toInstant()
java.time.Instant与java.sql.Timestamp Timestamp.from(instant) timestamp.toInstant()
java.time.ZonedDateTime与java.util.GregorianCalendar GregorianCalendar.from(zonedDateTime) cal.toZonedDateTime()
java.time.LocalDate与java.sql.Time Date.valueOf(localDate) date.toLocalDate()
java.time.LocalTime与java.sql.Time Date.valueOf(localDate) date.toLocalTime()
java.time.LocalDateTime与java.sql.Timestamp Timestamp.valueOf(localDateTime) timestamp.toLocalDateTime()
java.time.ZoneId与java.util.TimeZone Timezone.getTimeZone(id) timeZone.toZoneId()
java.time.format.DateTimeFormatter与java.text.DateFormat formatter.toFormat()

9.4 Java比较器

在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。

Java实现对象排序的方式有两种:

  • 自然排序:java.lang.Comparable
  • 定制排序:java.util.Comparator
1. 自然排序:java.lang.Comparable
  • Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。
  • 实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。如果当前对象this大于形参对象obj,则返回正整数,如果当前对象this小于形参对象obj,则返回负整数,如果当前对象this等于形参对象obj,则返回零。
  • 实现Comparable接口的对象列表(和数组)可以通过 Collections.sort 或 Arrays.sort进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
  • 对于类 C 的每一个 e1 和 e2 来说,当且仅当 e1.compareTo(e2) == 0 与 e1.equals(e2) 具有相同的boolean值时,类 C 的自然排序才叫做与 equals 一致。建议最好使自然排序与 equals 一致(不是必需的)。

Comparable 的典型实现:(默认都是从小到大排列的)

  • String:按照字符串中字符的Unicode值进行比较
  • Character:按照字符的Unicode值来进行比较
  • 数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较
  • Boolean:true 对应的包装类实例大于 false 对应的包装类实例
  • Date、Time等:后面的日期时间比前面的日期时间大

例子

class Goods implements Comparable {
    private String name;
    private double price;

    /**
     * 按照价格从低到高排序,如果价格相同,则按商品名排序
     *
     * @param o
     * @return
     */
    @Override
    public int compareTo(Object o) {
        if (o instanceof Goods) {
            Goods g = (Goods) o;
            if (this.price > g.price) {
                return 1;
            } else if (this.price < g.price) {
                return -1;
            } else {
                return this.name.compareTo(g.name);
            }

        }
        throw new RuntimeException("不是商品类型");
    }

    public Goods(String name, double price) {
        this.name = name;
        this.price = price;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

public class ComparableTest {
    public static void main(String[] args) {
        Goods[] goods = new Goods[6];
        goods[0] = new Goods("goods6", 100);
        goods[1] = new Goods("goods1", 200);
        goods[2] = new Goods("goods2", 500);
        goods[3] = new Goods("goods3", 50);
        goods[4] = new Goods("goods4", 100);
        goods[5] = new Goods("goods5", 300);

        System.out.println("排序前:");
        System.out.println(Arrays.toString(goods));

        Arrays.sort(goods);
        System.out.println("排序后:");
        System.out.println(Arrays.toString(goods));
    }
}
           
2. 定制排序:java.util.Comparator
  • 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序,强行对多个对象进行整体排序的比较。
  • 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示 o1小于o2。
  • 可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。
  • 还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。

例子

public class ComparatorTest {
    public static void main(String[] args) {
        String[] strings = new String[]{"A", "C", "B", "D", "E"};

        System.out.println("排序前:");
        System.out.println(Arrays.toString(strings));

        // 对strings进行降序排序
        Arrays.sort(strings, new Comparator() {

            @Override
            public int compare(Object o1, Object o2) {
                if (o1 instanceof String && o2 instanceof String) {
                    String s1 = (String) o1;
                    String s2 = (String) o2;
                    return -s1.compareTo(s2);
                }
                throw new RuntimeException("类型不对");
            }
        });
        System.out.println("排序后:");
        System.out.println(Arrays.toString(strings));
    }
}
           
3. Comparable和Comparator的比较
  • Comparable接口的方式一旦一定,保证Comparable接口实现类的对象在任何位置都可以比较大小。
  • Comparator接口属于临时性的比较。

9.5 System类

System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包。

由于该类的构造器是private的,所以无法创建该类的对象,也就是无法实例化该类。其内部的成员变量和成员方法都是static的,所以也可以很方便的进行调用。

1. 成员变量
  • System类内部包含in、out和err三个成员变量,分别代表标准输入流(键盘输入),标准输出流(显示器)和标准错误输出流(显示器)。
2. 成员方法
  • native long currentTimeMillis(): 该方法的作用是返回当前的计算机时间,时间的表达格式为当前计算机时间和GMT时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数。
  • void exit(int status): 该方法的作用是退出程序。其中status的值为0代表正常退出,非零代表异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。
  • void gc(): 该方法的作用是请求系统进行垃圾回收。至于系统是否立刻回收,则取决于系统中垃圾回收算法的实现以及系统执行时的情况。
  • String getProperty(String key): 该方法的作用是获得系统中属性名为key的属性对应的值。

系统中常见的属性名以及属性的作用

属性名 属性说明
java.version Java运行时环境版本
java.home Java安装目录
os.name 操作系统的名称
os.version 操作系统的版本
user.name 用户的账户名称
user.home 用户的主目录
user.dir 用户的当前工作目录

9.6 Math类

java.lang.Math提供了一系列静态方法用于科学计算。其方法的参数和返回值类型一般为double型。

方法 说明
abs 绝对值
acos,asin,atan,cos,sin,tan 三角函数
sqrt 平方根
pow(double a,doble b) a的b次幂
log 自然对数
exp e为底指数
max(double a,double b) 返回两数的较大值
min(double a,double b) 返回两数的较小值
random() 返回0.0到1.0的随机数
long round(double a) double型数据a转换为long型(四舍五入)
toDegrees(double angrad) 弧度—>角度
toRadians(double angdeg) 角度—>弧度

9.7 BigInteger与BigDecimal

1. 引入背景

Integer类作为int的包装类,能存储的最大整型值为2 31-1,Long类也是有限的,最大为2 63-1。如果要表示再大的整数,不管是基本数据类型还是他们的包装类都无能为力,更不用说进行运算了;同样浮点型也存在精度不准等问题。

2. BigInteger类

java.math包的BigInteger可以表示不可变的任意精度的整数。BigInteger 提供所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。另外,BigInteger还提供以下运算:模算术、GCD 计算、质数测试、素数生成、位操作以及一些其他操作。

构造器

  • BigInteger(String val):根据字符串构建BigInteger对象

常用方法

方法 说明
public BigInteger abs() 返回此 BigInteger 的绝对值的 BigInteger
BigInteger add(BigInteger val) 返回其值为 (this + val) 的 BigInteger
BigInteger subtract(BigInteger val) 返回其值为 (this - val) 的 BigInteger
BigInteger multiply(BigInteger val) 返回其值为 (this * val) 的 BigInteger
BigInteger divide(BigInteger val) 返回其值为 (this / val) 的 BigInteger(整数相除只保留整数部分)
BigInteger remainder(BigInteger val) 返回其值为 (this % val) 的 BigInteger
BigInteger[] divideAndRemainder(BigInteger val) 返回包含 (this / val) 后跟 (this % val) 的两个 BigInteger 的数组
BigInteger pow(int exponent) 返回其值为 (thisexponent) 的 BigInteger
3. BigDecimal

一般的Float类和Double类可以用来做科学计算或工程计算,但在商业计算中,要求数字精度比较高,故用到java.math.BigDecimal类。

BigDecimal类支持不可变的、任意精度的有符号十进制定点数。

构造器

  • public BigDecimal(double val)
  • public BigDecimal(String val)

常用方法

  • public BigDecimal add(BigDecimal augend)
  • public BigDecimal subtract(BigDecimal subtrahend)
  • public BigDecimal multiply(BigDecimal multiplicand)
  • public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)

下一篇:枚举类与注解