Java 进阶知识(九)

0 阅读6分钟

日期与日历

package date;
import java.util.Date;
/**
 * java.util.Date
 * Date的每一个实例用于表示一个时间点
 * 内部维护一个long值,该值记录的时自1970年
 * 1月1日 00:00:00到当前Date表示的时间之间所
 * 经过的毫秒。
 * 由于Date存在时区以及千年虫问题,所以大部分
 * 操作时间的方法都被声明为过时的不再建议使用
 * 了。
 * @author ta
 *
 */
public class DateDemo {
	public static void main(String[] args) {
		//默认创建表示当前系统时间
		Date date = new Date();
		System.out.println(date);
		//获取Date内部维护的long值
		long time = date.getTime();
		System.out.println(time);
		
		time = time+1000*60*60*24;
		date.setTime(time);
		System.out.println(date);
		
		date.setTime(0);
		System.out.println(date);
	}
}
package date;

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

/**
 * java.text.SimpleDateFormat
 * 该类可以将Date与String之间互转。依靠的是
 * 一个日期格式字符串。
 * @author ta
 *
 */
public class SimleDateFormat_format {
	public static void main(String[] args) {
		Date now = new Date();
		System.out.println(now);
		/*
		 * 2018-09-19 10:26:55
		 * yyyy-MM-dd HH:mm:ss
		 */
		SimpleDateFormat sdf
			= new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss"	
			);
		/*
		 * String format(Date date)
		 * 将给定的Date按照SDF指定的日期格式
		 * 转换为一个字符串
		 */
		String line = sdf.format(now);
		System.out.println(line);
		
	}
}
package date;

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

/**
 * 将一个字符串解析为一个Date
 * @author ta
 *
 */
public class SimpleDateFormat_parse {
	public static void main(String[] args) throws ParseException {
		String str = "2008-08-08 20:08:08";
		SimpleDateFormat sdf
			= new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss"	
			);		
		Date date = sdf.parse(str);
		System.out.println(date);
	}
}
package date;

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

/**
 * 编写一个程序,要求用户输入自己的生日,格式
 * 为:yyyy-MM-dd
 * 然后经过程序运算,输出到今天为止一共活了
 * 多少天.
 * 再输出其出生10000天的纪念日是哪天,输出格式
 * 同样为:yyyy-MM-dd
 * @author ta
 *
 */
public class Test {
	public static void main(String[] args) throws ParseException {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入您的生日:(yyyy-mm-dd)");
		String dateStr = scanner.nextLine();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date birth = sdf.parse(dateStr);
		Date now = new Date();
		long time = now.getTime()-birth.getTime();
		time = time/1000/60/60/24;
		System.out.println("恭喜您,已经活了"+time+"天,请继续保持!");
		time = birth.getTime()+1000L*60*60*24*10000;
		Date date = new Date(time);
		String line = sdf.format(date);
		System.out.println("您出生10000天的纪念日为:"+line);
	}
}
package date;

import java.util.Calendar;
import java.util.Date;

/**
 * java.util.Calendar
 * 日历类
 * Calendar是用来操作时间的API,使用非常的方
 * 便。但本身是一个抽象类,提供了一个用于获取
 * 实现类的静态方法:getInstance().该方法可以
 * 根据当前系统所在地区获取一个适用的实现类
 * 大部分地区获取回来的都是:GregorianCalendar
 * 即:阳历
 * @author ta
 *
 */
public class CalendarDemo1 {
	public static void main(String[] args) {
		//Calendar默认也表示当前系统时间
		Calendar calendar = Calendar.getInstance();
		/*
		 * Calendar的toString输出的信息很多
		 * 但是不能直观的看出具体日期
		 */
		System.out.println(calendar);
		/*
		 * Date getTime()
		 * Calendar提供的getTime方法可以获取
		 * 一个Date,该实例表示的就是当前Calendar
		 * 所表示的日期
		 */
		Date date = calendar.getTime();
		System.out.println(date);
		
		/*
		 * Calendar另一个方法:
		 * void setTime(Date date)
		 * 该方法可以让当前Calendar表示给定的Date
		 * 所表示的日期
		 */
	}
}
package date;

import java.util.Calendar;

/**
 * Calendar提供了获取各时间分量信息的方法:
 * int get(int field)
 * 参数为一个int值,不同的值表示不同的时间
 * 分量,而我们无需记忆这些数字,Calendar把
 * 这些数定义为了常量。
 * @author ta
 *
 */
public class CalendarDemo2 {
	public static void main(String[] args) {
		Calendar calendar = Calendar.getInstance();
		//获取年
		int year = calendar.get(Calendar.YEAR);
		//获取月(月从0开始)
		int month = calendar.get(Calendar.MONTH)+1;
		/*
		 * 获取日
		 * DAY_OF_MONTH 月中的天
		 * DATE         月中的天
		 * DAY_OF_WEEK  周中的天 
		 * DAY_OF_YEAR  年中的天
		 */
		int date = calendar.get(Calendar.DATE);
		
		System.out.println(year+"-"+month+"-"+date);
		
		int h = calendar.get(Calendar.HOUR_OF_DAY);
		int m = calendar.get(Calendar.MINUTE);
		int s = calendar.get(Calendar.SECOND);
		System.out.println(h+":"+m+":"+s);
		
		//查看今天是今年的第几天?
		int days = calendar.get(Calendar.DAY_OF_YEAR);
		System.out.println(days);
		
		//今天是周几?
		int dow = calendar.get(Calendar.DAY_OF_WEEK);
		String[] data = {"日","一","二","三","四","五","六"};
		System.out.println("周"+data[dow-1]);
		
		/*
		 * 获取指定的时间分量所允许的最大值
		 */
		days = calendar.getActualMaximum(Calendar.DAY_OF_YEAR);
		System.out.println(days);
	}
}
package date;

import java.util.Calendar;

/**
 * void set(int field,int value)
 * 对指定的时间分量设置指定的值
 * @author ta
 *
 */
public class CalendarDemo3 {
	public static void main(String[] args) {
		Calendar calendar = Calendar.getInstance();
		/*
		 * 表示2008-08-08 20:08:08
		 */
		calendar.set(Calendar.YEAR, 2008);
		calendar.set(Calendar.MONTH, Calendar.AUGUST);
		calendar.set(Calendar.DATE,3);
		calendar.set(Calendar.HOUR_OF_DAY, 20);
		calendar.set(Calendar.MINUTE, 8);
		calendar.set(Calendar.SECOND, 8);
		//下面的getTime输出如果注释掉,后面的输出结果不同
		System.out.println(calendar.getTime());
		/*
		 * 上面设置日期为8号,但是set方法并非在每次
		 * 设置后就真的将时间分量该对对应值,而是在
		 * getTime时进行实际计算,但是下面的代码在
		 * 设置星期几时会影响月中的天,这会导致刚才
		 * 设置的8号被覆盖等于没做。
		 * 对此的解决办法是,当设置出现相互影响时,
		 * 可以在之前设置过后主动调用一次getTime方法
		 * 让Calendar进行一次调整运算后再设置就没有
		 * 问题了
		 */
		calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
		System.out.println(calendar.getTime());
	}
}
package date;

import java.util.Calendar;

/**
 * void add(int field,int amount)
 * 对指定的时间分量累加给定值。若给定的值为
 * 负数则是减去。
 * 该操作与set不同,调用一次后就会真实进行一次
 * 计算操作。
 * @author ta
 *
 */
public class CalendarDemo4 {
	public static void main(String[] args) {
		Calendar calendar = Calendar.getInstance();
		/*
		 * 3年5个月零25天以后是哪天?
		 */
		//加3年
		calendar.add(Calendar.YEAR, 3);
		//加5个月
		calendar.add(Calendar.MONTH, 5);
		//加25天
		calendar.add(Calendar.DAY_OF_YEAR, 25);
		System.out.println(calendar.getTime());
		/*
		 * 查看当周的周六是哪天?
		 */
		calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
		System.out.println(calendar.getTime());
	}
}
package date;

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

/**
 * 计算商品促销日:
 * 输入一个商品的生产日期,格式(yyyy-MM-dd)
 * 再输入保质期的天数。
 * 然后经过程序运算输出该商品促销日期,格式
 * 也是:yyyy-MM-dd
 * 促销日计算规则:商品过期日前两周的周三
 * @author ta
 *
 */
public class Test2 {
	public static void main(String[] args) throws ParseException {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入生产日期:");
		String dateStr = scanner.nextLine();
		
		System.out.println("请输入保质期:");
		int days = Integer.parseInt(scanner.nextLine());
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date date = sdf.parse(dateStr);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		
		//计算促销日
		//1计算过日期
		calendar.add(Calendar.DAY_OF_YEAR, days);
		//2前两周
		calendar.add(Calendar.DAY_OF_YEAR, -14);
		//3设置为当周的周三
		calendar.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
		
		date = calendar.getTime();
		String line = sdf.format(date);
		System.out.println("促销日为:"+line);
	}
}

lambda

package lambda;
/**
 * lambda表达式
 * lambda可以让java以函数式编程。
 * 该特性是自JDK8之后推出的。
 * 使用lambda可以方便快捷创建匿名内部类。
 * 语法:
 * (参数列表)->{
 * 	 方法体
 * }
 * 使用lambda创建的匿名内部类实际所属的接口
 * 必须只能有一个方法。否则编译不通过
 * 
 * @author ta
 *
 */
public class LambdaDemo1 {
	public static void main(String[] args) {
		Runnable r1 = new Runnable() {
			public void run() {
				System.out.println("hello");
			}
		};
		
		Runnable r2 = ()->{
			System.out.println("hello");
		};
		/*
		 * 当方法中只有一句话时。方法的"{}"
		 * 可以省略
		 */
		Runnable r3 = ()->System.out.println("hello");
	}
}
package lambda;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class LambdaDemo2 {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("传奇");
		list.add("小泽老师");
		list.add("苍老师");
		System.out.println(list);
//		Comparator<String> com = new Comparator<String>() {
//			public int compare(String o1, String o2) {
//				return o1.length()-o2.length();
//			}
//		};
		/*
		 * 方法中的参数类型可以不再指定,编译器会结合
		 * 程序自行分析参数类型
		 */
//		Comparator<String> com = (o1,o2)->{
//			return o1.length()-o2.length();
//		};
		/*
		 * 如果只有一句代码那么在忽略"{}"号的同时,
		 * return关键字也要忽略。
		 */
		Comparator<String> com = (o1,o2)->o1.length()-o2.length();
		
		Collections.sort(list,com);
		System.out.println(list);
	}
}
package lambda;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * JDK8之后集合和Map都支持了一个新的方法:
 * foreach,可以使用lambda遍历集合元素。
 * 由于该方法是集合自行提供的,那么在使用一个
 * 线程安全的集合或Map时,该种遍历方式也是并发
 * 安全的(原迭代器模式不与集合方法互斥,并发
 * 需要自行维护)
 * @author ta
 *
 */
public class LambdaDemo3 {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("one");
		list.add("two");
		list.add("three");
		list.add("four");
		for(String str : list) {
			System.out.println(str);
		}
		//JDK8支持的新方式:
		list.forEach(
			(str)->System.out.println(str)
		);
		
		Map<String,Integer> map = new HashMap<String,Integer>();
		map.put("语文", 99);
		map.put("数学", 98);
		map.put("英语", 97);
		
		map.forEach(
			(k,v)->System.out.println(k+":"+v)	
		);
	}
}