21-常用的时间类和实现Comparable接口

Day21笔记

文章目录

  • Day21笔记
    • 一,自然排序和定制排序的区别
      • 1.实现Comparable接口
      • 2.实现Comparator接口
      • 3.Comparable和Comparator的区别所在
    • 二,JDK8之前的日期时间的API
      • 1.System下的currentTimeMillies()
      • 2.两个Date()类
      • 3.SimpleDateFormat类
      • 4.Calendar类
    • 三,String,StringBulider以及StringBuffer
      • 1.String和其他类的转化
      • 2.String和StringBuilder以及StringBuffer的区别

今日重点:
(1)掌握自然排序和定制排序的区别
(2)掌握System的currentTimeMills()方法和Date类
(3)掌SimpleDateFormat的使用及于字符串之间的转化
(4)掌握String和包装类、基本数据类型之间的转化
(5)掌握String和char数组、byte数组间的转化
(6)知晓String、StringBuffer、StringBuildr常用方法和区别

一,自然排序和定制排序的区别

实现对象排序的方法有两种

1.实现Comparable接口

2.实现Comparator接口

1.实现Comparable接口

  1. 像String、包装类、Date等已经实现了Comparable接口,则可以实现同一个类的不同对象的大小的比较。
 * 
 * 2. 默认情况下,String、包装类、Date等类型进行排序的话,默认从小到大的方式排序
 * 
 * 3. 自定义的类,要想实现排序,需要考虑实现Comparable接口,重写compareTo()。
 *    在此方法中,指明如何比较大小。
 *    标准:
 * 		如果当前对象大,返回正数
 * 		如果当前对象小,返回负数
 * 		如果两个对象相等,返回0
/*
	 * 根据对象的属性进行比较
	 * 自然排序
	 * 
	 */
	@Test
	public void test2() {

		Goods g1 = new Goods("Lenovo", 7800);
		Goods g2 = new Goods("Huawei", 8800);
		Goods g3 = new Goods("Dell", 5800);
		Goods g4 = new Goods("Xiaomi", 4800);
		Goods g5 = new Goods("HP", 9800);

		Goods[] goods = new Goods[] { g1, g2, g3, g4, g5 };

		for (int i = 0; i < goods.length; i++) {
			System.out.println(goods[i]);
		}

		System.out.println();
		Arrays.sort(goods);
		for (int i = 0; i < goods.length; i++) {
			System.out.println(goods[i]);
		}

	}

用于比较的javaBean

public class Goods implements Comparable {

	private String name;
	private double 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;
	}

	public Goods() {
		super();
	}

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

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

	@Override
	public int compareTo(Object o) {
		if (o instanceof Goods) {
				
			return -Double.compare(this.price, ((Goods) o).price);
		}
		throw new RuntimeException("类型不匹配!!");

	}

}

2.实现Comparator接口

问题的引入:
 * ① 针对于StringBuffer 或 StringBuilder的多个对象构成的数组,如何实现排序呢?
 * ② 针对于String、Date、包装类,如何实现从大到小的顺序排序呢?
 * 
 * 1. 除了使用自然排序之外,还可以使用定制排序:实现Comparator接口
 * 
 * 2. 步骤:
 *   ① 提供实现Comparator接口的类
 *   ② 重写compare(Object o1,Object o2),指明对象如何比较大小
 *   ③ 实例化Comparator接口的类,并在需要的位置使用即可。
	@Test
	public void test3() {

		Goods g1 = new Goods("Lenovo", 7800);
		Goods g2 = new Goods("Huawei", 8800);
		Goods g3 = new Goods("Dell", 5800);
		Goods g4 = new Goods("Xiaomi", 4800);
		Goods g5 = new Goods("HP", 9800);
		Goods g6 = new Goods("Apple", 9800);

		Goods[] goods = new Goods[] { g1, g2, g3, g4, g5, g6 };
		//匿名实现类
		Comparator comparator = new Comparator() {

			@Override
			public int compare(Object o1, Object o2) {
				if (o1 instanceof Goods && o2 instanceof Goods) {
					Goods g1 = (Goods) o1;
					Goods g2 = (Goods) o2;
					int result = -Double.compare(g1.getPrice(), g2.getPrice());
					if (result != 0) {
						return result;
					}
					return -g1.getName().compareTo(g2.getName());
				}
				throw new RuntimeException("类型匹配错误");
			}

		};

		Arrays.sort(goods, comparator);
		System.out.println();
		for (int i = 0; i < goods.length; i++) {
			System.out.println(goods[i]);
		}

	}

练习:String默认排序为从小到大排序,更改排序为从大到小


	@Test
	public void test4() {

		// 创建String类型的数组,按照字符串从大到小的顺序排序。
		String[] arr = new String[] { "AA", "DD", "CC", "ZZ", "GG" };
		System.out.println("未排序");
		System.out.println(Arrays.toString(arr));

		System.out.println("自然排序");
		Arrays.sort(arr);
		System.out.println(Arrays.toString(arr));

		Comparator comparator = 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("定制排序");
		Arrays.sort(arr, comparator);
		System.out.println(Arrays.toString(arr));

	}

3.Comparable和Comparator的区别所在

- Comparable:理解为一劳永逸的方式。

- Comparator:理解为一种临时的方式。

二,JDK8之前的日期时间的API

1.System下的currentTimeMillies()

/*
* 用来描述当前时间
* 通常使用它来描述时间差
* 
*/
	@Test
	public void test1() {

		long time = System.currentTimeMillis();
		System.out.println(time);

	}

2.两个Date()类

	/*
	 * java.util.Date
	 * 1. 两个构造器:Date() / Date(long millitime)
	 * 2. 两个方法:toString() / getTime()
	 * 
	 * 
	 */
	
	@Test
	public void test2() {
		//空参构造器以及他的两种方法toString()\getTime()
		Date date = new Date();
		System.out.println(date);//重写了toString()方法,输出的为:Fri Mar 13 19:25:42 CST 2020
		
		long time = date.getTime();//获取一个long的单位为毫秒的数字
		System.out.println(time);
		System.out.println(System.currentTimeMillis());
		
		System.out.println("******************************************************");
		//带参数的Date构造器以及它的两个方法
		Date date2 = new Date(date.getTime());
		System.out.println(date2);
		System.out.println(date);
		
		System.out.println(date.getTime());
		System.out.println(date2.getTime());
		
		System.out.println("******************************************************");
		
	}


	/*	
	 * 
	 * java.until.Date的子类:java.sql.Date
	 * 
	 */
	@Test
	public void test3() {
		
		java.sql.Date date = new java.sql.Date(1584098991151L);
		System.out.println(date);//2020-03-13,并不会输出时分秒
		
		System.out.println(date.getTime());//1584098991151
		
	}

3.SimpleDateFormat类

21-常用的时间类和实现Comparable接口_第1张图片


/*
	 * SimpleDateFormat:使用此类实现格式化和解析操作
	 * 
	 * 格式化:日期--->字符串
	 * 解析:字符串--->日期
	 * 
	 * 比如:"1995-03-01"转换为对应的日期对象
	 */
	/*
	 * SimpleDateFormat:使用此类实现格式化和解析操作
	 * 
	 * 格式化:日期--->字符串:formate方法
	 * 解析:字符串--->日期:parse方法,记得抛异常
	 * 
	 * 比如:"1995-03-01"转换为对应的日期对象
	 * 
	 * 重点:使用SimpleDateFormate对时间进行格式化输出
	 */
	@Test
	public void test4() throws ParseException {
		//SimpleDateFormate:使用此类实现格式化和解析操作
		SimpleDateFormat sdf = new SimpleDateFormat();
		Date date = new Date();
		
		//格式化:日期转化为字符串
		String strDate = sdf.format(date);
		System.out.println(strDate);//20-3-13 下午7:47
		
		//解析过程
		Date date2 = sdf.parse(strDate);
		System.out.println(date2.getTime());
		System.out.println("****************************************");
		//重点
		//使用SimpleDateFormat带参的构造器
		SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String strDate1 = sdf1.format(date2);
		System.out.println(strDate1);//2020-03-13 19:54:00
		
		
	}

4.Calendar类

@Test
	public void test5() {

		// 返回Calendar子类的一个对象
		Calendar calendar = Calendar.getInstance();
		System.out.println(calendar);

		// get()
		System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//当月的第几天
		System.out.println(calendar.get(Calendar.DAY_OF_WEEK));//当前周的第几天
		System.out.println(calendar.get(Calendar.DAY_OF_YEAR));//当前年的第几天

		// set()
		calendar.set(Calendar.DAY_OF_MONTH, 23);//设置为第多少天
		System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
		// add()
		calendar.add(Calendar.DAY_OF_MONTH, -2);//当前天数向前加减天数
		System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
		// getTime():获取当前日历对象对应的日期Date对象
		Date date = calendar.getTime();
		System.out.println(date);// Sat Mar 21 17:03:56 GMT+08:00 2020

		// setTime(Date d):使用指定的日期Date对象重置Calendar对象
		calendar.setTime(new Date());
		System.out.println(calendar.get(Calendar.DAY_OF_MONTH));

	}

三,String,StringBulider以及StringBuffer

1.String和其他类的转化

	/*
	 * String与包装类、基本数据类型之间的转化
	 */
	@Test
	public void test1() {
		
		String str1 = "123";
		
		int num = Integer.parseInt(str1);
		System.out.println(num);
		Integer integer = num;
		System.out.println(integer);
		int a = integer;
		System.out.println(a);
		String string = String.valueOf(a);
		
	}

}


	/*
	 * String与char[]之间的转化
	 
	 字符串-----》字符数组 通过toCharArray()
	 字符数组-----》转化为字符串 通过字符串的构造器
	 
	 */
	@Test
	public void test2(){
		String str1 = "hello";
		//String--->char[]:调动String的toCharArray()
		char[] arr1 = str1.toCharArray();
		for(int i = 0;i < arr1.length;i++){
			System.out.println(arr1[i]);
		}
		
		//char[] ---> String:调用String的构造器
		String str2 = new String(arr1, 0, arr1.length);//new String(arr1);
		System.out.println(str2);
	}
/*
	 * String与byte[]之间的转化
	 * 
	 * 
	 * 1. 关联:
	 * 内存层面:
	 * char:用2个字节存储
	 * 
	 * 存储层面:
	 * 一个char,应该用几个字节存储呢?跟字符集有关系,具体问题具体分析
	 * 
	 * ASCII:给26个英文大小写字母,0-9等都分配了对应的一个字节数值。比如:a --> 97   A--> 65
	 * GBK:兼容了ASCII(如果出现英文字母,0-9时,仍然使用1个字节存储),一个汉字使用2个字节存储
	 * UTF-8:兼容了ASCII(如果出现英文字母,0-9时,仍然使用1个字节存储),一个汉字使用3个字节存储
	 * 
	 * 2. 
	 * 编码: 字符、字符串--->字节、字节数组
	 * 	> 从看得懂的,转换为看不懂的。
	 * 
	 * 解码:字节、字节数组 --> 字符、字符串
	 *  > 从看不懂的,转换为看得懂的。
	 *  
	 * 结论:编码集要与解码集一致。否则会出现乱码!
	 */
	@Test
	public void test3() throws Exception{
		String str1 = "hello中国";
		//编码:String--->byte[]:getBytes()
		byte[] arr1 = str1.getBytes();//使用默认的字符集:UTF-8
		System.out.println(Arrays.toString(arr1));
		
		byte[] arr2 = str1.getBytes("gbk");//显式指定字符集。
		System.out.println(Arrays.toString(arr2));
		
		//解码:byte[] ---> String:使用构造器
		
		String str2 = new String(arr1);//使用默认的字符集:UTF-8
		System.out.println(str2);
		
		String str3 = new String(arr2);
		System.out.println(str3);//因为编码集和现在的解码集不一致,导致出现乱码!
		
		String str4 = new String(arr2,"gbk");
		System.out.println(str4);//因为编码集和现在的解码集都是使用gbk,没有乱码
	}
	
//String --> StringBuffer、StringBuilder
String str = "hello";
StringBuffer s1 = new StringBuffer(str);
StringBuilder s2 = new StringBuilder(str);

//StringBuffer、StringBuilder --> String
String str1 = s1.toString();
String str2 = s2.toString();

String str3 = new String(s1);
String str3 = new String(s2);

2.String和StringBuilder以及StringBuffer的区别

 /*
	 * 一、三个类的对比 
	 * String:不可变的字符序列; 底层使用char[]数组存储 
	 * StringBuffer:可变的字符序列;线程安全的,效率低;底层使用char[]数组存储 
	 * StringBuilder:可变的字符序列; jdk1.5引入,线程不安全的,效率高;底层使用char[]数组存储
	 * 
	 * 注意:在jdk8以后,String\StringBuffer\StringBuilder底层改成byte[]+字符集存储,节省内存空间。
	 * 
	 * 
	 * 1. StringBuffer与StringBuilder的主要区别就是StringBuffer中的方法声明为同步的了。 
	 * 2. String s0 = "";//new char[0]; 
	 * String s1 = "abc";// new char[]{'a','b','c'};
	 * 
	 * s1 += "de";//new char[]{'a','b','c','d','e'};
	 * 
	 * StringBuilder s2 = new StringBuilder();//char arr = new char[16];
	 * StringBuilder s3 = new StringBuilder("abc");//char arr = new char["abc".length() + 16]; 
	 * s2.append("abc");//arr[0] = 'a',arr[1] = 'b',arr[2] = 'c'; 
	 * 
	 * ... 
	 * 有可能底层arr的char[]存储不下了,此时需要扩容!默认扩容为原来容量的2倍+2
	 * 
	 * 启示: 
	 * 1. 开发中如果频繁的对字符串进行修改操作,建议使用StringBuffer/StringBuilder,替换String 
	 * 2.开发中如果不涉及线程安全问题或主动加锁,建议使用StringBuilder,替换StringBuffer 
	 * 3.开发中添加的字符串数据较多,建议使用StringBuilder(int capacity),替换StringBuilder()
	 */
	@Test
	public void test1() {
		String str1 = "hello";
		str1 += "world";// 新建一个内存空间保存helloworld

		StringBuffer str2 = new StringBuffer("hello");
		str2.append("world");// 与创建对象中的char[]数组是同一个
	}

三者的效率

/*
	 * 对比三者的执行效率
	 *   从高到低:
	 *   StringBuilder > StringBuffer > String
	 */
	@Test
	public void test3() {
		// 初始设置
		long startTime = 0L;
		long endTime = 0L;
		String text = "";
		StringBuffer buffer = new StringBuffer("");
		StringBuilder builder = new StringBuilder("");
		// 开始对比
		startTime = System.currentTimeMillis();
		for (int i = 0; i < 20000; i++) {
			buffer.append(String.valueOf(i));
		}
		endTime = System.currentTimeMillis();
		System.out.println("StringBuffer的执行时间:" + (endTime - startTime));
		
		
		startTime = System.currentTimeMillis();
		for (int i = 0; i < 20000; i++) {
			builder.append(String.valueOf(i));
		}
		endTime = System.currentTimeMillis();
		System.out.println("StringBuilder的执行时间:" + (endTime - startTime));
		
		
		startTime = System.currentTimeMillis();
		for (int i = 0; i < 20000; i++) {
			text = text + i;
		}
		endTime = System.currentTimeMillis();
		System.out.println("String的执行时间:" + (endTime - startTime));

	}


//常用方法

/*
	 * 
	 * 二、StringBuffer和StringBuilder中的常用方法
	 * 
	 * StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接 StringBuffer
	 * delete(int start,int end):删除指定位置的内容 
	 * StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str 
	 * StringBuffer insert(int offset,xxx):在指定位置插入xxx 
	 * StringBuffer reverse() :把当前字符序列逆转 
	 * public intindexOf(String str) 
	 * public String substring(int start,int end) 
	 * public int length() 
	 * public char charAt(int n ) 
	 * public void setCharAt(int n ,char ch)
	 * 
	 * 总结: 
	 * 增:append(xxx) 
	 * 删:delete(int start,int end) 
	 * 改:setCharAt(int n ,char ch) / replace(int start, int end, String str) 
	 * 查:charAt(int n ) 
	 * 插:insert(int offset, xxx)
	 * 长度:length() 
	 * 遍历:for + charAt() / toString()
	 * 
	 * 
	 *//*
	 * 
	 * 二、StringBuffer和StringBuilder中的常用方法
	 * 
	 * StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接 StringBuffer
	 * delete(int start,int end):删除指定位置的内容 
	 * StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str 
	 * StringBuffer insert(int offset,xxx):在指定位置插入xxx 
	 * StringBuffer reverse() :把当前字符序列逆转 
	 * public intindexOf(String str) 
	 * public String substring(int start,int end) 
	 * public int length() 
	 * public char charAt(int n ) 
	 * public void setCharAt(int n ,char ch)
	 * 
	 * 总结: 
	 * 增:append(xxx) 
	 * 删:delete(int start,int end) 
	 * 改:setCharAt(int n ,char ch) / replace(int start, int end, String str) 
	 * 查:charAt(int n ) 
	 * 插:insert(int offset, xxx)
	 * 长度:length() 
	 * 遍历:for + charAt() / toString()
	 * 
	 * 
	 */
```java

):删除指定位置的内容 
	 * StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str 
	 * StringBuffer insert(int offset,xxx):在指定位置插入xxx 
	 * StringBuffer reverse() :把当前字符序列逆转 
	 * public intindexOf(String str) 
	 * public String substring(int start,int end) 
	 * public int length() 
	 * public char charAt(int n ) 
	 * public void setCharAt(int n ,char ch)
	 * 
	 * 总结: 
	 * 增:append(xxx) 
	 * 删:delete(int start,int end) 
	 * 改:setCharAt(int n ,char ch) / replace(int start, int end, String str) 
	 * 查:charAt(int n ) 
	 * 插:insert(int offset, xxx)
	 * 长度:length() 
	 * 遍历:for + charAt() / toString()
	 * 
	 * 
	 */

你可能感兴趣的:(JavaSe学习)