beyond comparejava源码比较_字符串


包装类

包装类就是把基本数据类型封装到一个类中,并提供相应的属性和方法更方便的去操作基本数据类型。
切记,包装类不是为了取代基本数据类型。包装类位于java.lang包中,继承关系如下:


beyond comparejava源码比较_基本数据类型_02


其中,Number是一个抽象类,提供了包装类和基本数据类型的装换。其中定义xxxValue()用于转换成基本数据类型。子类(Byte,Short,Integer,Long,Float,Double)是根据其自身特性实现xxxValue()方法。

Integer

Integer包装了一个基本数据类型,提供了很多方法能在int类型和String类型之间互相转换。

public class Test01 {
	public static void main(String[] args) {
		
		// 【1】静态字段属性
		System.out.println(Integer.MAX_VALUE);
		System.out.println(Integer.MIN_VALUE);
		
		// 【2】构造方法
		// int->Integer
		Integer i1 = new Integer(10);
		System.out.println(i1.toString());
		
		// String->Integer
		// 可能会抛出NumberFormatException
		Integer i2 = new Integer("20");
		System.out.println(i2);
	}
}


常用方法


public class Test02 {
	public static void main(String[] args) {
		
		// 【1】xxxValue()
		Integer i1 = new Integer("20");
		int i1Value = i1.intValue();
		System.out.println(i1Value);
		
		// 【2】equals
		Integer i2 = new Integer(10);
		System.out.println(i1.equals(i2));
		
		
		// 【3】String -> 基本数据类型
		int a = Integer.parseInt("100");
		
		
		// 把String按照进制解析(C)
		int b = Integer.parseInt("1010", 2);
		System.out.println(b);
		// 把十进制转化成对于基数的字符串(C)
		String str1 = Integer.toBinaryString(10);
		System.out.println(str1);
		
		// 【4】 基本数据类型 -> String
		String str2 = Integer.toString(10);
		System.out.println(str2);
		
		// 【5】String、int -> Integer
		Integer i3 = Integer.valueOf(100);
		Integer i4 = Integer.valueOf("200");
		System.out.println(i3);
		System.out.println(i4);
		
	}
}


总结

基本数据类型 <-> 包装类

Integer(int)

ValueOf(int)

xxxValue()

String <-> 包装类

Integer(String)

ValueOf(String)

toString();

基本数据类型 <- 包装类 -> String

static toString(int):String

static ParseInt(String):int

Comparable接口

这个接口提供了对两个对象进行自然排序(比较大小)。实现该接口的类具有比较大小的能力。其中定义的compareTo()用于比较大小,其返回值a.compareTo(b) -> r


beyond comparejava源码比较_System_03


public class Test03 {
	public static void main(String[] args) {
		
		Integer i1 = Integer.valueOf(20);
		Integer i2 = Integer.valueOf(10);
		
		System.out.println(i1.compareTo(i2));
		
	}
}


自动拆箱和自动装箱

自动装箱:jvm编译时会把基本数据类型自动转化为对应的包装类,称为自动装箱(auto-boxing)


// 【1】 自动装箱
Integer i2 = 20; // Integer.valueOf(20); 
System.out.println(i2.toString());


自动拆箱:jvm在编译时会把包装类自动转化成对应的基本数据类型,称为自动拆箱(auto-unboxing)


// 【2】 自动拆箱
int a = i2;
System.out.println(a);


String

String 类代表字符串。java程序中的所有字符串字面值(如“abc”)都作为此类的实例实现。

  • 字符串是常量;它们的值在创建之后不能更改。因为String对象是不可变的,所以可以共享。
  • 字符连成一串构成了字符串,本质上,字符串就是字符数组。
  • 字符数组长度不可变,同时String类没有提供修改字符数组的方法,所以字符串是常量。

构造方法

String提供了很多构造方法,其中可以根据字节数组构造字符串,也可以通过字符数组构造字符串。


// 【1】
		// new 分配在堆区
		String str1 = new String("hello");
		// 常量池
		String str2 = "hello";
		System.out.println(str1 == str2);
		
		// 通过字节数组构建字符串
		byte[] buf3 = {97,98,99};
		// win7简体中文 平台默认字符串
		System.out.println(Charset.defaultCharset());
		
		String str3 = new String(buf3);
		System.out.println(str3);
		
		// 通过指定字符集解码指定字节数组
		// GBK字节序列
		byte[] buf4 = {-42,-48,-71,-6};
		// String str4 = new String(buf4,"GBK");
		// 解码自定长度的字节数组
		String str4 = new String(buf4, 0, 2, "GBK");
		System.out.println(str4);
		
		// UTF-8字节序列
		byte[] buf5 = {-28, -72, -83, -27, -101, -67};
		String str5 = new String(buf5, "UTF-8");
		System.out.println(str5);
		
		// 通过指定字符数组构建字符串
		char[] cbuf6 = {'中','国','你','好'};
		// String str6 = new String(cbuf6);
		String str6 = new String(cbuf6,0,3);
		System.out.println(str6);


常用方法:

字符串比较


// 【1】字符串的比较
		String str2 = "abc";
		String str3 = "aBc";
		// 查看源代码:总结字符串比较规则
		System.out.println(str2.compareTo(str3));

		// 不区分大小写的比较
		System.out.println(str2.compareToIgnoreCase(str3));

		// 比较内容是否相等,只有当大小写完全一致才行
		System.out.println(str2.contentEquals(str3));

		// 重写Object equals
		System.out.println(str2.equals(str3));
		System.out.println(str2.equalsIgnoreCase(str3));

		// 实战:控制台输入验证码
		String str4 = "a1Bf";
		System.out.println("请输入验证码:" + str4);
		Scanner sc = new Scanner(System.in);
		String iptStr = sc.next();
		if(str4.equalsIgnoreCase(iptStr)) {
			System.out.println("验证码正确");
		}else {
			System.out.println("验证码输入失败");
		}


查找字符串(子串)


// 字符串连接(+)
		String str1 = "hello";
		String str2 = " world";
		String str3 = str1.concat(str2);
		System.out.println(str3);

		// 查找子串
		System.out.println(str3.contains("he2"));

		// 以自定后缀结尾
		System.out.println(str3.endsWith("ld"));
		// 实战:检查文件是否是mp3文件
		String fileName = "abc.mp3";
		System.out.println(fileName.endsWith(".mp3"));

		// 以指定前缀开始
		fileName = "kal20190713.png";
		System.out.println(fileName.startsWith("kal2019"));
		// 从指定位置判断是否有前缀
		System.out.println(fileName.startsWith("2019", 3));

		// indexOf
		String str4 = "hoello123";
		// 从左向右查找指定字符第一个出现的位置,如果没查到返回-1
		System.out.println(str4.indexOf('a'));
		// 从左向右从指定位置开始查找指定字符第一个出现的位置,如果没查到返回-1		
		System.out.println(str4.indexOf('1', 5));
		
		// 从左向右查找指定字符串第一个出现的位置,如果没查到返回-1
		System.out.println(str4.indexOf("ll"));
		//indexOf(String str, int fromIndex) 
		
		// lastIndexOf
		// 从右向左查找指定字符第一个出现的位置,如果没查到返回-1
		System.out.println(str4.lastIndexOf('o'));
		// 从右向左查找指定位置指定字符第一个出现的位置,如果没查到返回-1
		System.out.println(str4.lastIndexOf('o',2));
		
		// lastIndexOf(String str) 
		// lastIndexOf(String str, int fromIndex)
		
		// 通过正则表达式 匹配检测是否包含指定正则表达式的字符串
		String str5 = "18620011234";
		System.out.println(str5.matches("186d{8}"));


格式化字符串


beyond comparejava源码比较_System_04


// 字符串格式化
		int a = 10;
		int b = 2;
		
		// format(String format, Object... args) 
		// ... 可变参数 jdk1.5 新特性
		String str1 = String.format("%d / %d = %d", a,b,a/b);
		System.out.println(str1);
		
		int price = 998;
		String str2 = String.format("¥ %d", price);
		System.out.println(str2);
		
		
		double price2 = 998.123;
		// IllegalFormatConversionException
		// String str3 = String.format("¥ %d", price2);
		
		// 保留2位小数
		String str3 = String.format("¥ %.2f", price2);
		System.out.println(str3);


字符串编码成字节数组


public static void main(String[] args) {

		// 字符串编码成字节数组
		String str1 = "abc中国";
		// GBK
		byte[] buf1 = str1.getBytes();
		System.out.println(Arrays.toString(buf1));
		
		// 指定字符集
		// UnsupportedEncodingException
		byte[] buf2 = null;
		try {
			buf2 = str1.getBytes("UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		System.out.println(Arrays.toString(buf2));
	}


字符串替换、分割


package com.kal3;

import java.util.Arrays;

public class Test05 {
	public static void main(String[] args) {
		
		// 替换字符串
		String str1 = "hello world";
		String str2 = str1.replace('o', 'x');
		System.out.println(str2);
		
		String str3 = str1.replace("ll", "xx");
		System.out.println(str3);
		
		// 正则替换
		String str4 = "abc123abc";
		// String str5 = str4.replaceAll("[a-z]{3}", "hello");
		String str5 = str4.replaceFirst("[a-z]{3}", "hello");
		System.out.println(str5);
		
		// 实战:把电话号码中的-替换成空字符
		String str6 = "186-2001-9812";
		String str7 = str6.replaceAll("-", "");
		System.out.println(str7);
		
		// 分割字符串
		String str8 = "186-2001-9812";
		String[] str8Arr = str8.split("-");
		System.out.println(Arrays.toString(str8Arr));
		
		// 实战:快速构建一个数组,其中包含26个大写字母
		String str9 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		String[] str9Arr = str9.split("");
		System.out.println(Arrays.toString(str9Arr));
		
		// 需求:请产生验证码时,产生中文
		
	}
}


其他的操作(子串、大小写转换、去空白)


// 【1】验证是否为空
		System.out.println("12".isEmpty());
		
		// 【2】求子串
		String str1 = "abc456";
		// beginIndex 开始位置
		//String str2 = str1.substring(3);
		
		// 含头不含尾
		String str2 = str1.substring(3,4);
		System.out.println(str2);
		
		// 大小写
		String str3 = "abc";
		System.out.println(str3.toUpperCase());
		String str4 = "ABc";
		System.out.println(str4.toLowerCase());
		
		/*String str5 = "a1Bf";
		System.out.println("请输入验证码:" + str5);
		Scanner sc = new Scanner(System.in);
		String iptStr = sc.next();
		
		if(str5.toLowerCase().equals(iptStr.toLowerCase())) {
			System.out.println("验证码正确");
		}else {
			System.out.println("验证码输入错误");			
		}*/
		
		// 去空白
		String str6 = "  abc      ";
		System.out.println(str6.length());
        //中间的空格去不掉
		System.out.println(str6.trim().length());


类型转化

通过静态方法String.valueOf()基本数据类型转化成字符串


public class Test07 {
	public static void main(String[] args) {
	
		String str1 = String.valueOf(10);
		System.out.println(str1);
	}
}


字符串中的陷阱

不可变字符串String进行任何方法的调用都会产生新字符串,所以在使用过程中一定防止以下情况产生,特别在循环中。


String str1 = "a";
str1 += "b";


StringBuffer和StringBuilder

StringBuffer和StringBuilder是字符串的可变版本。它们内部维护了一个“容器”,其提供了很多方法对“容器”中的字符进行增、删、改、查。

StringBuffer

线程安全的可变字符序列。


public static void main(String[] args) {

		// string buffer
		// 默认容器容量是容纳16个字符
		StringBuffer sb = new StringBuffer();
		// 【1】添加操作
		sb.append("a");
		sb.append("hello");
		sb.append(4);
		System.out.println(sb);
		
		// 输出字符串长度
		System.out.println(sb.length());
		System.out.println(sb.capacity());
		
		// 【2】insert 
		sb.insert(0, "ABC");
		sb.insert(0, 10);
		System.out.println(sb);
		
		// 【3】拓容
		sb.append("12345");
		// System.out.println(sb.capacity());
	}


  1. StringBuffer默认构造对象时容器容量是16个字符。
  2. 随着字符数量的增加、StringBuffer会自动扩容。
  3. 扩容的规则:随着向StringBuffer添加新元素,如果空间有余,直接添加;如果空间不足,按照oldLength*2 + 2的规则通过数组复制的方式扩容。
public static void main(String[] args) {

		StringBuffer sb = new StringBuffer(30);
//		System.out.println(sb.capacity());
		sb.append("helloworld");
		
		// 【1】删除
		// sb.delete(0, 5);
		// sb.deleteCharAt(0);
		System.out.println(sb);
		
		// 【2】手动扩容,不管原来多少,直接变成100,如果变小会输出原来的要缩短用setLength
		sb.ensureCapacity(100);
		System.out.println(sb.capacity());
		
		// 【3】修改操作
		sb.setCharAt(0, 'H');
		System.out.println(sb);
		
		// 【4】修改字符串的长度
		// sb.setLength(5);
		// 多用于清空操作
		sb.setLength(0);
		System.out.println(sb);
		
		// 【6】自动缩短容器
		sb.append("he");
		sb.trimToSize();
		System.out.println(sb.capacity());
	}


StringBuilder

线程不安全的字符串可变序列,不保证同步。

StringBuffer和StringBuilder的区别?

StringBuilder:可变字符序列、效率高、线程不安全 jdk1.5

StringBuffer:可变字符序列、效率低、线程安全jdk1.0

日期时间类

计算机如何表示时间?

在计算机中,规定格林尼治(GMT)时间为世界协调时(UTC),其他地区的时间都是在UTC的基础上进行时区偏移得到的。

时间戳

Date在计算机表示日期时间类,位于java.util包中。
Date本质上是一个包装类,包装了一个long类型的值,表示Date对象距离历元经历的毫秒数(时间戳timestamp)。

public static void main(String[] args) {

		// 【1】Date
		Date date = new Date();
		// Sat Jul 13 16:04:29 CST(China Standard Time) 2019
		System.out.println(date.toString());
		
		// 获取距离历元的毫秒数
		long ts = date.getTime()
		System.out.println(ts);
		
		// 需求:创建一个时间表示明天的此刻
		long ts2 = ts + 24 * 60 * 60  * 1000;
		Date date2 = new Date(ts2);
		System.out.println(date2);
		
		// 需求:国庆距离现在有几天?
		
String datestr2 = "2020年2月25日";
		SimpleDateFormat df2 =new SimpleDateFormat();
		df2.applyPattern("yyyy年MM月dd日");
		Date datestr3=null;
		try {
			datestr3=df2.parse(datestr2);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(datestr3.getTime());//转化为时间戳
		long date4 = datestr3.getTime()-date2.getTime();
		System.out.println(date4/1000/3600/24);

		
		// 【2】时间的比较
		// 需求:比较date和date2的大小
		if(date.getTime() < date2.getTime()) {
			System.out.println("date2 大");
		}else {
			System.out.println("date2 小");
		}
		
		System.out.println(date.before(date2));
		System.out.println(date2.after(date));
		
		System.out.println(date.compareTo(date2));
		
	}


getTime()获取时间戳

setTime(long)设置日期时间对象的时间戳

日期时间格式化


public static void main(String[] args) {

		// date
		// 根据系统当前时区、当前时间创建一个对象
		Date date1 = new Date();
		//System.out.println(date1.toString());
		 
		// 需求:格式化时间为xxxx年xx月xx日  xx时xx分xx秒
		// 把日期->日期字符串
		SimpleDateFormat df = new SimpleDateFormat();
		// df.applyPattern("yyyy年MM月dd日 HH时mm分ss秒.SSS");
		df.applyPattern("yyyy年MM月dd日 HH时mm分ss秒");
		String dateStr = df.format(date1);
		System.out.println(dateStr);
		
		// 把日期字符串->日期时间
		String dateStr2 = "2019年07月13日";
		/*
		SimpleDateFormat df2 = new SimpleDateFormat();
		df2.applyPattern("yyyy年MM月dd日");
		*/
		df.applyPattern("yyyy年MM月dd日");
		
		Date date2 = null;
		try {
			date2 = df.parse(dateStr2);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		System.out.println(date2);
	}


Calendar

日历本质上是一个包装类,包装了个特定的瞬间(就是时间戳),且在日历内部提供了很多字段(YEAR、MONTH、DAY_OF_MONTH、HOUR等),这些字段已经在Calendar计算好存在Calendar对象的容器中,只需要开发者去Calendar对象去获取即可。