文章目录
String、StringBuffer 和 Stringbuilder类
字符串就是一连串的字符序列,Java提供了 String和 Stringbuffer两个类来封装字符串,并提供子一系列方法来操作字符串对象。
String类是不可变类,即一旦一个 String对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。
Stringbuffer对象则代表一个字符序列可变的字符串,当一个 Stringbuffer被创建以后,通过String Buffer提供的 append、 inserto、 reverse、 setcharato、 setlengtho等方法可以改变这个字符串对象的字符序列。一旦通过 String Buffer生成了最终想要的字符串,就可以调用它的 tostring(方法将其转换为一个 String对象。
从JDK1.5开始出现的 StringBuilder类,也代表字符串对象。实际上, Stringbuilder和 Stringbuffer基本相似。两个类的构造器和方法也基本相同。不同的是, StringBuffer是线程安全的,而 StringBuilder则没有实现线程安全功能,所以性能略高。
因此在通常情况下,如果需要创建一个内容可变的字符串对象,则应该优先考虑使用 StringBuilder类。然后使用toString转换为String
public class StringDemo {
static String Foo() {
return "AB";
}
public static void main(String[] args) {
String str1 = "ABCD";
String str2 = "A" + "B" + "C" + "D";
String str3 = "AB" + "CD";
String str4 = new String("ABCD");
final String tmp = "AB";
String str5 = tmp + "CD";
String str6 = Foo() + "CD";
System.out.println(str1 == str2);// true
System.out.println(str1 == str3);// true
System.out.println(str1 == str4);// false
System.out.println(str1 == str5);// false
System.out.println(str1 == str6);// false
System.out.println("-----------------");
System.out.println("Bbc".compareTo("abc"));//-31
// String 的创建转换
char[] cs = {'A','l','l','e','n'};
String str = new String(cs);
char[] cs2 = str.toCharArray();
byte[] bs = {65,66,67};
str = new String(bs);//"ABC"
byte[] bs2 = str.getBytes();
// String 获取字符串信息
str = "abcAbcEDF";
System.out.println(str.charAt(0));
System.out.println(str.indexOf("Ab"));//3 第一次出现Ab的索引
System.out.println(str.lastIndexOf("b"));//4 最后一次出现b的索引
// String 比较
System.out.println("abv".equals("abv"));//true
System.out.println("abv".equalsIgnoreCase("abV"));//true
System.out.println("leno".contentEquals("leno"));//true contentEquals 相当于 equals
System.out.println("leno".contentEquals("leno"));//true
// String 大小写转换
System.out.println("abc".toUpperCase());
System.out.println("abc".toLowerCase());
// String 获取子字符串
System.out.println("abcdefg".substring(3));//"defg"
System.out.println("abcdefg".substring(3,5));//"de"
// 分割字符串,(以“”为整体作为分隔符,前向的),其实参数1是正则表达式
String[] temp1 = "abcdefga".split("a");// "","bcdefg"
String[] temp2 = "abcdefghi".split("fg");// "abcde","hi"
String[] temp3 = "abcdefghi".split("[f,g]");// "abcde","","hi"
String[] temp4 = "abcdefghi".split("[fg]");// "abcde","","hi"
String[] temp5 = "abcdefga".split("a", 0);// "","bcdefg"
String[] temp6 = "abcdefga".split("a", -1);// "","bcdefg",""
//字符串以什么开头或结尾
System.out.println("hello.txt".startsWith("hello"));//true
System.out.println("hello.txt".startsWith(""));//true
System.out.println("hello.txt".startsWith("hello.txt"));//true
System.out.println("hello.txt".endsWith(".txt"));//true
System.out.println("hello.txt".endsWith(""));//true
System.out.println("hello.txt".endsWith("hello.txt"));//true
}
}
public class StringDemo2 {
public static void main(String[] args) {
// 比较 String、StringBuffer、StringBuilder 拼接3000次字符串 的耗时
test1();//1806
test2();//2
test3();//1
//结论:拼接字符串,尽量用StringBuffer、StringBuilder
}
// String
private static void test1() {
String str1 = "";
long begin = System.currentTimeMillis();
for (int i = 0; i < 30000; i++) {
str1 += i;
}
long end = System.currentTimeMillis();//
System.out.println(end - begin);
}
// StringBuffer
private static void test2() {
StringBuffer str1 = new StringBuffer("");
long begin = System.currentTimeMillis();
for (int i = 0; i < 30000; i++) {
str1.append(i);
}
long end = System.currentTimeMillis();//
System.out.println(end - begin);
}
// StringBuilder
private static void test3() {
StringBuilder str1 = new StringBuilder("");
long begin = System.currentTimeMillis();
for (int i = 0; i < 30000; i++) {
str1.append(i);
}
long end = System.currentTimeMillis();//
System.out.println(end - begin);
}
}
Math
import java.math.BigDecimal;
import java.math.BigInteger;
public class MathDemo {
public static void main(String[] args) {
double d = Math.abs(-9.9);
System.out.println(d);
d = Math.sin(Math.PI);
System.out.println(d);
// 浮点数的运算有精度问题,解决:BigDecimal类
System.out.println(0.09 + 0.01);// 0.09999999999999999
System.out.println(1.0 - 0.33);// 0.6699999999999999
System.out.println(0.0023 * 100);// 0.22999999999999998
System.out.println(12.3 / 100);// 0.12300000000000001
BigDecimal d1 = new BigDecimal("0.09");// 注意使用String类似构造,若使用double等构造仍然不精确
BigDecimal d2 = new BigDecimal("0.01");
System.out.println(d1.add(d2));// 0.10
d1 = new BigDecimal("1.0");
d2 = new BigDecimal("0.33");
System.out.println(d1.subtract(d2));// 0.67
d1 = new BigDecimal("0.0023");
d2 = new BigDecimal("100");
System.out.println(d1.multiply(d2));// 0.2300
d1 = new BigDecimal("12.3");
d2 = new BigDecimal("100");
System.out.println(d1.divide(d2));// 0.123
// BigInteger 用于解决超出long最大值的运算的
long num = Long.MAX_VALUE;
System.out.println(num);// 9223372036854775807
System.out.println(num + 1);// -9223372036854775808
System.out.println(BigInteger.valueOf(num).add(BigInteger.valueOf(1)));// 9223372036854775808
// static double random() 返回值为 double值为正号,大于等于 0.0 ,小于 1.0 。 [0,1)
// 打印 [0, 100)的随机数
for (int i = 0; i < 10; ++i) {
int randomNum = (int) (Math.random() * 100);
System.out.println(randomNum);
}
System.out.println("-------------------------------");
// static long round(double a) 返回参数中最接近的 long ,其中 long四舍五入为正无穷大。
long n = Math.round(4.5);
System.out.println(n);//5
}
}
ThreadlocalRandom 和 Random
Random类专门用于生成一个伪随机数,它有两个构造器:一个构造器使用默认的种子(以当前时间作为种子), 另一个构造器需要程序员显式传入一个long型整数的种子。
ThreadlocalRandom类是Java7新增的一个类,它是 Random的增强版。在并发访问的环境下,使用 Threadlocalrandom来代替 Random可以减少多线程资源竟争,最终保证系统具有较好的性能。
例子:
Random random = new Random();
boolean b = random.nextBoolean();
System.out.println(b);
byte[] buffer = new byte[16];
random.nextBytes(buffer);
System.out.println(Arrays.toString(buffer));
//生成 0~1.0 之间的伪随机数double
double d = random.nextDouble();
System.out.println(d);
//生成 0~1.0 之间的伪随机数float
float f = random.nextFloat();
System.out.println(f);
//生成一个标准正态分布的随机数
System.out.println(random.nextGaussian());
//生成一个int取值范围的随机整数
System.out.println(random.nextInt());
//生成一个[0,26)的随机整数
System.out.println(random.nextInt(26));
//生成一个long取值范围的随机整数
System.out.println(random.nextLong());
BigDecimal
double d = 0.1 + 0.05;
System.out.println(d);//0.15000000000000002
//为了解决浮点数精度问题
//使用BigDecimal (尽量使用String去构造)
BigDecimal f1 = new BigDecimal(0.02);
BigDecimal f2 = BigDecimal.valueOf(0.02);
BigDecimal f3 = new BigDecimal("0.02");
System.out.println(f1);//0.0200000000000000004163336342344337026588618755340576171875
System.out.println(f2);//0.02
System.out.println(f3);//0.02
BigDecimal f4 = new BigDecimal("0.04");
System.out.println(f4.add(f2));//0.06
System.out.println(f4.subtract(f2));//0.02
System.out.println(f4.multiply(f2));//0.0008
System.out.println(f4.divide(f2));//2
Date
是指java.util.Date 而不是 java.sql.Date
- Date( ):生成一个代表当前日期时间的Date对象。该构造器在底层调用 System.currentTimeMillis获得long整数作为日期参数。
- Date( long date);根据指定的long型整数来生成一个Date对象。该构造器的参数表示创建的Date对象和GMT1970年1月1日00:00:00之间的时间差,以毫秒作为计时单位
Date构造器相同的是,Date对象的大部分方法也 Deprecated了,剩下为数不多的几个方法
- boolean after( Date when):测试该日期是否在指定日期when之后
- boolean before( Date when):测试该日期是否在指定日期when之前。
- int compareto( Date anotherdate):比较两个日期的大小,后面的时间大于前面的时间时返回-1,否则返回1。
- boolean equals( Object obj):当两个时间表示同一时刻时返回true
- long getTime():返回该时间对应的long型整数,即从GMT1970-01-01 00:00:00 到该Date对象之间的时间差,以毫秒作为计时单位。
- void setTime (long time):设置该Date对象的时间。
下面程序示范了Date类的用法
Date date = new Date();
System.out.println(date);//Sat Nov 28 21:28:50 CST 2020
System.out.println(date.toLocaleString());//2020-11-28 21:28:50
Date d2 = new Date(System.currentTimeMillis()+1000);//1000ms之后的时间
System.out.println(d2.toLocaleString());//2020-11-28 21:28:51
System.out.println(date.compareTo(d2));//-1
System.out.println(date.before(d2));//true
Date <–>String
public class StringUtil {
private StringUtil() {}
/**
* 判断字符串是否为null或空白符或空字符串
* @param str 待判断的字符串
* @return boolean
*/
public static boolean IsNullOrBlank(String str) {
if(str == null || "".equals(str.trim()) )
return true;
return false;
}
}
public class DateUtil {
private static String DEFAULT_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";
private DateUtil() {}
// 格式化操作:将 Date --> String
public static String date2string(java.util.Date date)
{
return date2string(date, null);
}
// 格式化操作:将 Date --> String
public static String date2string(java.util.Date date, String strPattern)
{
if(StringUtil.IsNullOrBlank(strPattern))
{
strPattern = DEFAULT_DATE_PATTERN;
}
return new SimpleDateFormat(strPattern).format(date);
}
// 解析操作:将字符串 String 转换为 Date
public static java.util.Date string2date(String strDateTime) throws ParseException
{
return string2date(strDateTime, null);
}
// 解析操作:将字符串 String 转换为 Date
public static java.util.Date string2date(String strDateTime, String strPattern) throws ParseException
{
if(StringUtil.IsNullOrBlank(strPattern))
strPattern = DEFAULT_DATE_PATTERN;
SimpleDateFormat sdf = new SimpleDateFormat(strPattern);
java.util.Date date = sdf.parse(strDateTime);
return date;
}
// 设置Date的时分秒都为0
public static void clearHourMinuteSecond(java.util.Date date)
{
if(null == date)
return;
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
}
public static void main(String[] args) throws ParseException {
System.out.println(date2string(new java.util.Date()," "));
System.out.println(DateUtil.string2date("2020-12-21 12:12:12",null));
}
}
Calendar
import java.util.Calendar;
public class CalendarDemo {
public static void main(String[] args) {
// 由于Date类中的有些方法过时了,但还能用,官方建议使用Calendar类(比Date强大)
Calendar cal = Calendar.getInstance();//获取当前日期和时间
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;//注意:0~11表示1~12月,故+1
int day = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
int milliSecond = cal.get(Calendar.MILLISECOND);//10:04:15.250 PM the MILLISECOND is 250.
//从 1970-01-01 00:00:00 UTC 到现在的毫秒数
long mil = System.currentTimeMillis();
long l = new java.util.Date().getTime();
String str = String.format("%d-%02d-%02d %02d:%02d:%02d.%d",
year, month, day, hour, minute, second, milliSecond);
System.out.println(str);
System.out.println("-----------------------");
// Calendar <--> Date
java.util.Date date = cal.getTime();
cal.setTime(date);
// void add(int field, int amount) 根据日历的规则,将指定的时间量添加或减去给定的日历字段。
cal.add(Calendar.DAY_OF_MONTH, 100);//100天后的日期
System.out.println(cal.getTime().toLocaleString());
}
}
import java.util.Calendar;
public class CalendarDemo2 {
public static void main(String[] args) {
//查询:最近一周
java.util.Date date = new java.util.Date();
DateUtil.clearHourMinuteSecond(date);
System.out.println(date);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
java.util.Date endDate = cal.getTime();
cal.add(Calendar.DAY_OF_MONTH, -7);
java.util.Date beginDate = cal.getTime();
System.out.println(endDate);
System.out.println(cal.getTime());
}
}