常用类(三)
Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,格里高利历)的偏移量。
人们对于时间的认识是:某年某月某日,这样的日期概念。计算机是long类型的数字。通过Calendar在二者之间搭起桥梁。而且Calendar提供了很多关于日期时间计算的方法。
GregorianCalendar(公历)是Calendar的一个具体子类,提供了世界上大多数国家/地区使用的标准日历系统。
注意:
月份:一月是0,二月是1,以此类推,12月是11
星期:周日是1,周二是2,。。。。周六是7
//默认语言环境的时间(时区) Calendar c = new GregorianCalendar(); /* * java.util.GregorianCalendar[ * time=1480667849712, * 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=2016, * MONTH=11, * WEEK_OF_YEAR=49,//本年第49周 * WEEK_OF_MONTH=1,//本月第1周 * DAY_OF_MONTH=2, * DAY_OF_YEAR=337,//本年第337天 * DAY_OF_WEEK=6, * DAY_OF_WEEK_IN_MONTH=1, * AM_PM=1, //下午 * HOUR=4, * HOUR_OF_DAY=16, //HOUR是12小时制, HOUR_OF_DAY是24小时制 * MINUTE=37, * SECOND=29, * MILLISECOND=712, * ZONE_OFFSET=28800000, * DST_OFFSET=0] */ |
public static void main(String[] args) { //默认语言环境的时间(时区) Calendar c = new GregorianCalendar();
int year=c.get(Calendar.YEAR); int month=c.get(Calendar.MONTH); int date=c.get(Calendar.DAY_OF_MONTH);
int hour=c.get(Calendar.HOUR_OF_DAY); int minute=c.get(Calendar.MINUTE); int second=c.get(Calendar.SECOND); int mill=c.get(Calendar.MILLISECOND); int week=c.get(Calendar.DAY_OF_WEEK);
StringBuffer dateStr=new StringBuffer(); dateStr.append(year).append("年"); dateStr.append(month+1).append("月"); dateStr.append(date).append("日").append(" "); dateStr.append(hour).append("时"); dateStr.append(minute).append("分"); dateStr.append(second).append("秒"); dateStr.append(mill).append("毫秒").append(" ");
String[] weeks={"日","一","二","","四","五","六"}; dateStr.append("星期").append(weeks[week-1]);
System.out.println(dateStr); } |
public static void main(String[] args) { Calendar c = new GregorianCalendar(2015, 6, 13); // c.set(2016, Calendar.DECEMBER, 4, 12, 12, 0); // c.setTime(new Date()); //15天之后 //c.add(Calendar.DATE, 15); //2个月之前 //c.add(Calendar.DAY_OF_MONTH, -2); //12小时之后 c.add(Calendar.HOUR, 12);
Date time = c.getTime();//转成日期 System.out.println(time); } |
public static Calendar getInstance()使用默认时区和语言环境获得一个日历。返回的 Calendar 基于当前时间,使用了默认时区和默认语言环境。
public static Calendar getInstance(TimeZone zone, Locale aLocale)使用指定时区和语言环境获得一个日历。返回的 Calendar 基于当前时间,使用了给定的时区和给定的语言环境。
public static void main(String[] args) { Calendar c = Calendar.getInstance(); System.out.println(c);
Calendar c2 = Calendar.getInstance(TimeZone.getTimeZone("Asia/Shanghai"), Locale.CHINA); System.out.println(c2);
Calendar c3 = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"), Locale.US); System.out.println(c3); } |
10.5.5 java.text.DateFormat和SimpleDateFormat
完成字符串和时间对象的转化:
l String format(date)
l Date parse(string)
public static void main(String[] args) { Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss 是本年的第几D"); System.out.println(sf.format(date));
String s = "2016-12-01 14:12:23"; SimpleDateFormat sf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { Date d = sf2.parse(s); System.out.println(d); } catch (ParseException e) { e.printStackTrace(); } } |
10.6 数学相关类Math、BigInteger、BigDecimal
10.6.1 java.lang.Math类
java.lang.Math提供了一系列静态方法用于科学计算;其方法的参数和返回值类型一般为double型。
l abs 绝对值
l acos,asin,atan,cos,sin,tan 三角函数
l sqrt 平方根
l pow(double a,doble b) a的b次幂
l log 自然对数
l exp e为底指数
l max(double a,double b)
l min(double a,double b)
l random() 返回0.0到1.0的随机数
l long round(double a) double型数据a转换为long型(四舍五入)
l toDegrees(double angrad) 弧度—>角度
l toRadians(double angdeg) 角度—>弧度
@Test public void test1() { System.out.println(Math.random());//随机值 System.out.println(Math.round(1.8));//四舍五入 保留整数部分 System.out.println(Math.floor(1.2));//1.0 向下取 System.out.println(Math.ceil(1.2));//2.0 向上取 System.out.println(Math.floor(-2.4));//-3.0 System.out.println(Math.ceil(-2.4));//-2.0 } |
10.6.2 java.math包的BigInteger和BigDecimal
Integer类作为int的包装类,能存储的最大整型值为231-1,Long类也是有限的,最大为263-1如果要表示再大的整数,不管是基本数据类型还是他们的包装类都无能为力,更不用说进行运算了。
java.math包的BigInteger可以表示不可变的任意精度的整数。BigInteger 提供所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。另外,BigInteger 还提供以下运算:模算术、GCD 计算、质数测试、素数生成、位操作以及一些其他操作。
l 构造方法
n BigInteger(String val):根据字符串构建BigInteger对象
l 常用方法
n BigInteger add(BigInteger val) :返回其值为 (this + val) 的 BigInteger。
n BigInteger subtract(BigInteger val) :返回其值为 (this - val) 的 BigInteger。
n BigInteger multiply(BigInteger val) :返回其值为 (this * val) 的 BigInteger。
n BigInteger divide(BigInteger val) :返回其值为 (this / val) 的 BigInteger。整数相除只保留整数部分。
n BigInteger remainder(BigInteger val) :返回其值为 (this % val) 的 BigInteger。
n BigInteger[] divideAndRemainder(BigInteger val):返回包含 (this / val) 后跟 (this % val) 的两个 BigInteger 的数组。
n BigInteger pow(int exponent) :返回其值为 (thisexponent) 的 BigInteger。
@Test public void test2(){ // long num1 = 12345678901234567890L;//out of range 超过long的范围 BigInteger num1 = new BigInteger("12345678901234567890"); BigInteger num2 = new BigInteger("92345678901234567890");
// System.out.println("和:" + (num1 + num2));//错误的 System.out.println("和:" + num1.add(num2)); System.out.println("减:" + num1.subtract(num2)); System.out.println("乘:" + num1.multiply(num2)); System.out.println("除:" + num2.divide(num1));//两个整数相除只保留整数部分 System.out.println("幂次方:" + num2.pow(5)); } |
一般的Float类和Double类可以用来做科学计算或工程计算,但是在商业计算中,要求数字精度比较高,所以用到java.math.BigDecimal类。BigDecimal类支持不可变的、任意精度的有符号十进制定点数。
l 构造器
n BigDecimal(double val)
n BigDecimal(String val)
l 常用方法
n BigDecimal add(BigDecimal augend) :返回一个 BigDecimal,其值为 (this + augend),其标度为 max(this.scale(), augend.scale())。
n BigDecimal subtract(BigDecimal subtrahend) :返回一个 BigDecimal,其值为 (this - subtrahend),其标度为 max(this.scale(), subtrahend.scale())。
n BigDecimal multiply(BigDecimal multiplicand):返回一个 BigDecimal,其值为 (this × multiplicand),其标度为 (this.scale() + multiplicand.scale())。
n BigDecimal pow(int n) :返回其值为 (thisn) 的 BigDecimal,准确计算该幂,使其具有无限精度。
n BigDecimal divide(BigDecimal divisor): 返回一个 BigDecimal,其值为 (this / divisor),其首选标度为 (this.scale() - divisor.scale());如果无法表示准确的商值(因为它有无穷的十进制扩展),则抛出 ArithmeticException。
n BigDecimal divide(BigDecimal divisor, int roundingMode) :返回一个 BigDecimal,其值为 (this / divisor),其标度为 this.scale()。
n BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) :返回一个 BigDecimal,其值为 (this / divisor),其标度为指定标度。
@Test public void test3(){ BigDecimal num1 = new BigDecimal("-12.1234567890123456567899554544444332"); BigDecimal num2 = new BigDecimal("89.6734567890123456567899554544444333"); System.out.println("和:" + num1.add(num2)); System.out.println("减:" + num1.subtract(num2)); System.out.println("乘:" + num1.multiply(num2)); System.out.println("除:" + num2.divide(new BigDecimal("2")));//可以整除(除尽)就对,不能整除就报异常 System.out.println("除:" + num2.divide(num1,BigDecimal.ROUND_HALF_UP)); System.out.println("除:" + num2.divide(num1,BigDecimal.ROUND_DOWN));//往零的方向舍去 System.out.println("除:" + num2.divide(num1,BigDecimal.ROUND_FLOOR));//往小的方向舍去 System.out.println("除:" + num2.divide(num1,BigDecimal.ROUND_CEILING));//往大的方向舍去 } |
10.7 比较器:自然排序与定制排序
10.7.1 自然排序:java.lang.Comparable
Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo(T t) 方法被称为它的自然比较方法。当前对象this与指定对象t比较“大小”,如果当前对象this大于指定对象t,则返回正整数,如果当前对象this小于指定对象t,则返回负整数,如果当前对象this等于指定对象t,则返回零。
实现Comparable接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort)进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
Comparable的典型实现:
l String:按照字符串中字符的Unicode值进行比较
l Character:按照字符的Unicode值来进行比较
l 数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较
l Date、Time等:后面的日期时间比前面的日期时间大
10.7.2 定制排序:java.util.Compartor
强行对某个对象 collection 进行整体排序 的比较函数。可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序。
10.7.3 示例
package com.api.compare;
import java.text.Collator; import java.util.Arrays; import java.util.Comparator; import java.util.Locale;
public class TestCompare {
@SuppressWarnings("unchecked") public static void main(String[] args) { Goods[] all = new Goods[4]; all[0] = new Goods("《红楼梦》",100); all[1] = new Goods("《西游记》",80); all[2] = new Goods("《三国演义》",140); all[3] = new Goods("《水浒传》",120);
Arrays.sort(all);
System.out.println(Arrays.toString(all));
Arrays.sort(all , new Comparator() {
@Override public int compare(Object o1, Object o2) { Goods g1 = (Goods) o1; Goods g2 = (Goods) o2;
return Collator.getInstance(Locale.CHINA).compare(g1.getName(),g2.getName()); } });
System.out.println(Arrays.toString(all)); }
} class Goods implements Comparable{ private String name; private double price; public Goods(String name, double price) { super(); this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "商品名:" + name + ", 价格:" + price; } @Override public int compareTo(Object o) { Goods other = (Goods) o; if(this.price > other.price){ return 1; }else if(this.price < other.price){ return -1; } return 0; }
} |