1,StringBuffer类
String的内容一旦声明则不可改变,如果改变,则改变的肯定是String的引用地址,如果现在要一个字符串经常改变,此时就必须使用StringBuffer类。
String:https://shao12138.blog.csdn.net/article/details/110419283#t9****
1.1,String&StringBuffer&StringBuilder
String 字符串常量、StringBuffer 字符串变量(线程安全)、StringBuilder 字符串变量(非线程安全)
- String类是不可变类,即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变 的,直至这个对象被销毁。
- StringBuffer对象则代表一个字符序列可变的字符串,当一个StringBuffer被创建以后,通过 StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等方法可以改变这个字 符串对象的字符序列。一旦通过StringBuffer生成了最终想要的字符串,就可以调用它的toString()方法 将其转换为一个String对象。
- **java.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。****StringBuffer、StringBuilder都代表可变的字符串对象,它们有共同的父类 AbstractStringBuilder ,并且两个类的构造方法和成员方法也基本相同。****不同的是,StringBuffer 是线程安全的,而StringBuilder是非线程安全的,所以StringBuilder性能略高。**如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同(是否添加了synchronize)。
在 Java 中,final 修饰的变量表示该变量的值不能被修改,但是如果 final 修饰的是对象引用,那么该对象的内容是可以被修改的。
1.2,StringBuffer基本方法
|---------------------------------------------------------------|--------|---------------------------------------------------------------------------------|
| 方法定义 | 类型 | 描述 |
| public StringBuffer() | 构造 | StringBuffer的构造方法 |
| public StringBuffer append(char c) | 方法 | 在StringBuffer中提供了大量的追加操作(类似于String中的+操作)可以向StringBuffer中追加内容,此方法可以添加任何数据类型。 |
| public StringBuffer append(String str) | 方法 | 在StringBuffer中提供了大量的追加操作(类似于String中的+操作)可以向StringBuffer中追加内容,此方法可以添加任何数据类型。 |
| public StringBuffer append(StringBuffer sb) | 方法 | 在StringBuffer中提供了大量的追加操作(类似于String中的+操作)可以向StringBuffer中追加内容,此方法可以添加任何数据类型。 |
| public int indexOf(String str) | 方法 | 查找指定字符串是否存在 |
| public int indexOf(String str,int fromIndex) | 方法 | 在指定位置处加上指定字符类型。 |
| public StringBuffer insert(int offset,String str) | 方法 | 在指定位置处加上指定字符类型。 |
| public StringBuffer reverse() | 方法 | 将内容反转保存 |
| public StringBuffer replace(int start,int end,String str) | 方法 | 指定内容替换 |
| public int length() | 方法 | 求出内容长度 |
| public StringBuffer delete(int start,int end) | 方法 | 删除指定范围的字符串 |
| public String substring(int start) | 方法 | 字符串截取,指定开始点 |
| public String subString(int start,int end) | 方法 | 截取指定范围的字符串 |
| public String toString() | 方法 | Object类继承的方法,用于将内容变为String类型 |
1, 字符串连接操作
StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("1,");stringBuffer.append("2"); System.out.println(stringBuffer); ================================================ 1,2 public class HelloWord { public static void main(String[] args) { StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("1,");stringBuffer.append("2"); System.out.println(stringBuffer); update(stringBuffer); System.out.println(stringBuffer); } public static void update(StringBuffer stringBuffer){ stringBuffer.append("-ysy"); } } ================================================= 1,2 1,2-ysy
从程序运行结果来看,将StringBuffer对象的内容传递到了fun()方法后,对StringBuffer的内容进行修改,而且操作完毕后修改的内容将被保留下来,所以与String比较StringBuffer的内容是可以修改的。
2,在任意位置处为StringBuffer添加内容
public class HelloWord { public static void main(String[] args) { StringBuffer buffer = new StringBuffer(); buffer.append("JAVA"); buffer.insert(0,"Hello "); System.out.println(buffer); } } ================================== Hello JAVA
3,字符串反转操作
public static void main(String[] args) { StringBuffer buffer = new StringBuffer(); buffer.append("JAVA"); buffer.reverse().toString(); System.out.println(buffer); } ========================================= AVAJ
4,替换指定范围的内容
public static void main(String[] args) { StringBuffer buffer = new StringBuffer(); buffer.append("Hello ");buffer.append("World!!"); buffer.replace(6,11,"JAVA"); System.out.println(buffer); } ================================ Hello JAVA!!
5,字符串截取
public class HelloWord { public static void main(String[] args) { StringBuffer buffer = new StringBuffer(); buffer.append("Hello ");buffer.append("World!!"); String str=buffer.substring(6,11); System.out.println(str); } } ============================================= World
6,删除指定范围的字符串
public class HelloWord { public static void main(String[] args) { StringBuffer buffer = new StringBuffer(); buffer.append("Hello ");buffer.append("World!!"); buffer.delete(6,14); System.out.println(buffer); } } ========================================== Hello
7,查找内容是否存在
public class HelloWord { public static void main(String[] args) { StringBuffer buffer = new StringBuffer(); buffer.append("Hello ");buffer.append("World!!"); if(buffer.indexOf("Hello")==-1){ System.out.println("没有找到指定的内容!"); }else{ System.out.println("可以查找到指定的内容!"); } } } ================================== 可以查找到指定的内容!
1.3,字符串拼接
拼接字符串有很多种方式,其中最常用的有4种:
- **+ 运算符:**如果拼接的都是字符串直接量,则适合使用 "+" 运算符实现拼接;
如果拼接的都是字符串直接量,则在编译时编译器会将其直接优化为一个完整的字符串,和你直接写一个完整的字符串是一样的,所以效率非常的高。(案例:https://shao12138.blog.csdn.net/article/details/110419283#t11** ) 如果拼接的字符串中包含变量,则在编译时编译器采用StringBuilder对其进行优化,即自动创建 StringBuilder实例并调用其append()方法,将这些字符串拼接在一起,效率也很高。但如果这个拼接操作是在循环中进行的,那么每次循环编译器都会创建一个StringBuilder实例,再去拼接字符串,相当于执行了 new StringBuilder().append(str) ,所以此时效率很低。**
- **StringBuilder:**如果拼接的字符串中包含变量,并不要求线程安全,则适合使用StringBuilder;
- **StringBuffer:**如果拼接的字符串中包含变量,并且要求线程安全,则适合使用StringBuffer;
**StringBuilder/StringBuffer都有字符串缓冲区,缓冲区的容量在创建对象时确定,并且默认为 16。****当拼接的字符串超过缓冲区的容量时,会触发缓冲区的扩容机制,即缓冲区加倍。**缓冲区频繁的扩容会降低拼接的性能,所以如果能提前预估最终字符串的长度,则建议在创建可变 字符串对象时,放弃使用默认的容量,可以指定缓冲区的容量为预估的字符串的长度。
- **String类的concat方法:**如果只是对两个字符串进行拼接,并且包含变量,则适合使用concat方法;
**concat方法的拼接逻辑是,先创建一个足以容纳待拼接的两个字符串的字节数组,然后先后将两 个字符串拼到这个数组里,最后将此数组转换为字符串。**在拼接大量字符串的时候,concat方法的效率低于StringBuilder。但是只拼接2个字符串时, concat方法的效率要优于StringBuilder。并且这种拼接方式代码简洁,所以只拼2个字符串时建议 优先选择concat方法。
2,Runtime类
2.1,认识Runtimel类
**在Java中Runtime类表示运行时操作类,是一个封装了JVM进程的类,每一个JVM都对应着一个Runtime类的实例,此实例由JVM运行时为其实例化。所以在JDK文档中读者不会发现任何有关Runtime类中的构造方法的定义,这是因为Runtime类本身的构造方法是私有化的(单例模式),**如果想取得一个Runtime实例,只能通过Runtime run = Runtime.getRuntime(); 在Runtime类中提供了一个静态的getRuntime()方法,此类可以取得Runtime类的实例,因此可以获得一些系统的信息。
|------------------------------------------------------------|---------------------|
| 方法 | 描述 |
| public static Runtime getRuntime() | 获取Runtime类的实例 |
| public long freeMemory() | 返回Java虚拟机中空闲内存量 |
| public long maxMemory() | 返回JVM的最大内存量 |
| public void gc() | 运行垃圾回收器,释放空间 |
| public Process exec(String command) throws IOException | 执行本机命令 |
2.2,获得JVM的内存空间
使用Runtime类可以取得JVM中的内存空间,包括最大内存空间、空闲内存空间等。
public class HelloWord { public static void main(String[] args) { Runtime run = Runtime.getRuntime(); System.out.println("JVM最大内存量:"+run.maxMemory()); System.out.println("JVM空闲内存量:"+run.freeMemory()); String str = ""; for (int i=0;i<10000;i++){ str+=i; } System.out.println("执行完String后,JVM空闲内存量:"+run.freeMemory()); run.gc(); System.out.println("垃圾回收之后,JVM空闲内存量:"+run.freeMemory()); } } ======================================= JVM最大内存量:1870135296 JVM空闲内存量:123520464 执行完String后,JVM空闲内存量:483809768 垃圾回收之后,JVM空闲内存量:763100448
2.3,Runtime类与Process类
除了观察内存使用情况外,也可以直接使用Runtime类运行本机的可执行程序,例如打开笔记本,关闭记事本。
public class HelloWord { public static void main(String[] args) { Runtime run = Runtime.getRuntime(); Process pro = null; try { pro = run.exec("notepad.exe"); Thread.sleep(3000); pro.destroy(); //关闭程序 }catch (Exception e){ e.printStackTrace(); } } }
3,System类
System类是一些与系统相关属性和方法的集合,而且在System类中的所有的属性都是静态的,要想引用这些属性和方法,直接使用System类调用即可。
System类中的方法都是使用static定义的,也就是都是静态的,所以在使用时直接使用类名称就可以调用。
|-----------------------------------------------------------------------------------------|-----------------------------|
| 方法定义 | 描述 |
| public static void exit(int status) | 系统退出,如果status为非0就表示退出 |
| public static void gc() | 运行垃圾收集机制,调用的是Runtime类中的gc方法 |
| public static long currentTimeMillis() | 返回毫秒为单位的当前时间 |
| public static void arraycopy(Object src,int srcPos,Object dest,int destPost,int length) | 数组复制操作 |
| public static Properties getProperties() | 获取当前系统的全部属性 |
| public static String getProperty(String key) | 根据键值取得属性的具体内容 |
1,计算一个程序的执行时间
public class HelloWord { public static void main(String[] args) { long startTime = System.currentTimeMillis(); int sum = 0; for (int i=0;i<3000000;i++){ sum += i; } long endTime = System.currentTimeMillis(); System.out.println("计算所花费时间:"+(endTime-startTime)+"毫秒"); } } ===================================== 计算所花费时间:4毫秒
**2,获取本机的全部环境属性:**文件默认编码,文件分隔符
System.getProperties().list(System.out); ======================================== -- listing properties -- java.runtime.name=Java(TM) SE Runtime Environment sun.boot.library.path=E:\Java\jdk-1.8\jre\bin java.vm.version=25.151-b12 java.vm.vendor=Oracle Corporation java.vendor.url=http://java.oracle.com/ path.separator=; java.vm.name=Java HotSpot(TM) 64-Bit Server VM file.encoding.pkg=sun.io user.script= user.country=CN ......
3,列出指定属性
public class HelloWord { public static void main(String[] args) { System.out.println("系统版本为:"+System.getProperty("os.name")+"----"+ System.getProperty("os.version")+"----"+ System.getProperty("os.arch")); System.out.println("系统用户为:"+System.getProperty("user.name")); System.out.println("当前用户目录为:"+System.getProperty("user.dir")); } } ============================================= 系统版本为:Windows 10----10.0----amd64 系统用户为:Bing 当前用户目录为:E:\Idea\workspace\Java
4,日期操作类
4.1,Date类
Java提供了Date类来处理日期、时间,Date对象即包括日期,也包括时间。Date类从JDK1.0起就存在了,所以它大部分构造器、方法都已过时,不再推荐使用了。
Date date = new Date(); System.out.println("当前日期为:"+date); ===================================== 当前日期为:Sun Dec 20 12:07:19 CST 2020
虽然已经取得了系统的当前日期,但是对于此日期可以发现格式并不是符合正常看到的格式,而且时间也不能准确精准到毫秒,要想按照用户自定义格式显示,可以使用Calendar类完成。
4.2,Calendar类
Calendar类可以取得的时间精确到毫秒。但是,这个类本身是个抽象类,不能直接实例化,只能通过子类继承父类的实例化操作,Calendar的子类是GregorianCalendar类。
Calendar类中的常量:
|------------------------------------------|-----|------------|
| public static final int YEAR | int | 取得年 |
| public static final int MONTH | int | 取得月 |
| public static final int DAY_OF_MONTH | int | 取得日 |
| public static final int HOUR_OF_DAY | int | 取得小时,24小时制 |
| public static final int MINUTE | int | 取得分 |
| public static final int SECOND | int | 取得秒 |
| public staitc final int MILLISECOND | int | 取得毫秒 |Calendar类中提供的方法:
|------------------------------------------|-----------------|
| public static Calendar getInstance() | 根据默认的时区实例化对象 |
| public boolean after(Object when) | 判断一个日期是否在指定日期之后 |
| public boolean before(Object when) | 判断一个日期是否在指定日期之前 |
| public int get(int field) | 返回给定日历字段值 |import java.util.Calendar; import java.util.GregorianCalendar; public class HelloWord { public static void main(String[] args) { Calendar calendar = null; calendar = new GregorianCalendar(); System.out.println("年:"+calendar.get(Calendar.YEAR)); System.out.println("月:"+(calendar.get(Calendar.MONDAY)+1)); System.out.println("日:"+calendar.get(Calendar.DAY_OF_MONTH)); System.out.println("时:"+calendar.get(Calendar.HOUR_OF_DAY)); System.out.println("分:"+calendar.get(Calendar.MINUTE)); System.out.println("秒:"+calendar.get(Calendar.SECOND)); System.out.println("毫秒:"+calendar.get(Calendar.MILLISECOND)); } } ============================================================== 年:2020 月:12 日:20 时:14 分:45 秒:49 毫秒:505
4.3,DateFormat类
Date类实际上取得时间是一个非常正确的时间。但是因为其显示格式不理想, 所以无法符合人们的习惯,就需要进行格式化处理编程符合人们习惯的日常格式。
DateFormat类是一个抽象类,所以肯定无法直接实例化,但是再此抽象类中提供了一个静态方法,可以直接取得本类的实例。
|------------------------------------------------------------------------------------------------|------------------|
| 方法 | 描述 |
| public static final DateFormat getDateInstance() | 得到默认对象 |
| public static final DateFormat getDateInstance(int style,Locale aLocate) | 根据Locate得到对象 |
| public static final DateFormat getDateTimeInstance(int dateStyle,int timeStyle,Locale aLocale) | 根据Locate得到日期时间对象 |public class HelloWord { public static void main(String[] args) { DateFormat df1 = null; DateFormat df2 = null; df1 = DateFormat.getDateInstance(); df2 = DateFormat.getDateTimeInstance(); System.out.println("DATE:"+df1.format(new Date())); System.out.println("DATETIME:"+df2.format(new Date())); } } =========================== DATE:2020-12-20 DATETIME:2020-12-20 14:56:20
如果想得到更更更合理的显示效果,可以指定其显示风格。
df1 = DateFormat.getDateInstance(DateFormat.YEAR_FIELD,new Locale("zh","CN")); df2 = DateFormat.getDateTimeInstance(DateFormat.YEAR_FIELD,DateFormat.ERA_FIELD,new Locale("zh","CN")); ================= DATE:2020年12月20日 DATETIME:2020年12月20日 下午02时59分52秒 CST
4.4,SimpleDateFormat类
**首先必须定义出一个完整的日期转换模板,在模板中通过特定的日期标记可以将一个日期类格式中的日期数字提取出来。**日期格式化标记模板:
|--------|---------------------------------|
| 标记 | 描述 |
| y | 年,年份是4位数字,所以需要yyyy |
| M | 年中的月份,月份是两位数字,所以需要MM表示 |
| d | 月中的天数,天数是两位数字,所以需要使用dd表示 |
| H | 一天中的小时数(24小时),小时是两位数,使用HH表示 |
| m | 小时中的分钟数,分钟是两位数字,使用mm表示 |
| s | 分钟中的描述,秒是两位数字,使用ss表示 |
| S | 毫秒数,毫秒数是3位数字,使用SSS表示 |常用方法:
|------------------------------------------------------------|--------|-------------------------------|
| 方法 | 类型 | 描述 |
| public SimpleDateFormat(String pattern) | 构造 | 通过一个指定的模板构造对象 |
| public Date parse(String source) throws ParseException | 普通 | 将一个包含日期的字符串变为Date类型 |
| public final String format(Date date) | 普通 | 将一个Date类型按照指定格式变为String类型 |public class HelloWord { public static void main(String[] args) { String pat1 = "yyyy-MM-dd HH:mm:SSS";//模板1 String pat2 = "yyyy年MM月dd日HH时mm分ss秒SSS毫秒";//模板2 SimpleDateFormat sdf1 = new SimpleDateFormat(pat1); SimpleDateFormat sdf2 = new SimpleDateFormat(pat2); try{ Date date = new Date(); System.out.println(sdf2.format(date)); }catch (Exception e){ e.printStackTrace(); } } } ==================================== 2020年12月20日15时17分58秒964毫秒
5,Math类&Random类
5.1,Math类
Math中提供了绝对值,三角函数等,都是静态方法,通过类名直接调用即可。
System.out.println("平方根:"+Math.sqrt(9.0)); System.out.println("求两数的最大值:"+Math.max(10,30)); System.out.println("求两数的最小值:"+Math.min(10,30)); System.out.println("2的3次方:"+Math.pow(2,3)); System.out.println("四舍五入:"+Math.round(33.6)); ===================================== 平方根:3.0 求两数的最大值:30 求两数的最小值:10 2的3次方:8.0 四舍五入:34
5.2,Random类
Random类时随机数产生类,可以指定一个随机数的范围,然后任意产生再次范围中的数字。
|----------------------------------|------------------|
| public boolean nextBoolean() | 随机产生boolean值 |
| public double nextDouble() | 随机生成double值 |
| public float nextFloat() | 随机生成float值 |
| public int nextInt() | 随机生成int值 |
| public long nextLong() | 随即生成long值 |Random r = new Random(); for (int i = 0; i < 10; i++) { System.out.print(r.nextInt(10)+" "); } ============================= 8 4 8 7 1 7 7 2 9 4
6,NumberFormat类、DecimalFormat类、SimpleDateFormate类
6.1,NumberFormat类
NumberFormat类表示数字的格式化类,即按照本地的风格吸光进行数字的显示。
|---------------------------------------------------------------------|-----------------|
| 方法 | 描述 |
| public static Locale[] get AvailableLocales() | 返回所有环境的数组 |
| public static final NumberFormat getInstance() | 返回当前默认语言环境的数字格式 |
| public static NumberFormat getInstance(Locale inLocale) | 返回指定语言环境的数字格式 |
| public static final NumberFormat getCurrencyInstance() | 返回当前默认环境的货币格式 |
| public static NumberFormat getCurrencyInstance(Locale inLocale) | 返回指定语言环境的数字格式 |public class HelloWord { public static void main(String[] args) { NumberFormat nf = null; nf = NumberFormat.getInstance(); System.out.println("格式化之后的数字:"+nf.format(100000)); System.out.println("格式化之后的数字:"+nf.format(1000.34)); } } =========================================== 格式化之后的数字:100,000 格式化之后的数字:1,000.34
6.2,DecimalFormat类
DecimalFormat类是Format类的一个子类,主要作用是格式化字数字。
|-------------|-----------|-----------------------------------|
| 标记 | 位置 | 描述 |
| 0 | 数字 | 代表阿拉伯数字,每一个0表示一位阿拉伯数字,如果该位不存在则显示0 |
| # | 数字 | 代表阿拉伯数字,每一个#表示以为阿拉伯数字,如果该位不存在则不显示 |
| . | 数字 | 小数点分隔符或货币的小数分隔符 |
| - | 数字 | 代表负号 |
| , | 数字 | 分组分隔符 |
| E | 数字 | 分隔科学计数法中的尾数和指数 |
| ; | 子模式边界 | 分割正数和负数子模式 |
| % | 前缀或后缀 | 数字乘以100并显示为百分数 |
| \u2030 | 前缀 | 乘以1000并显示为千分位 |
| \u00A4 | 前缀或后缀 | 货币记号,由货币号替换 |class FormatDemo{ public void format1(String pattern,double value){ DecimalFormat df = null; df = new DecimalFormat(pattern); String str = df.format(value); System.out.println("使用"+pattern+"格式化数字"+value+": "+str); } } public class HelloWord { public static void main(String[] args) { FormatDemo demo = new FormatDemo(); demo.format1("###,###.###",111222.34567); demo.format1("000,000.000",11222.34567); demo.format1("###,###.###¥",11222.34567); demo.format1("000,000.000¥",111222.34567); demo.format1("##.###%",0.345678); demo.format1("00.###%",0.0345678); demo.format1("###.###\u2030",0.345678); } } ==================================== 使用###,###.###格式化数字111222.34567: 111,222.346 使用000,000.000格式化数字11222.34567: 011,222.346 使用###,###.###¥格式化数字11222.34567: 11,222.346¥ 使用000,000.000¥格式化数字111222.34567: 111,222.346¥ 使用##.###%格式化数字0.345678: 34.568% 使用00.###%格式化数字0.0345678: 03.457% 使用###.###‰格式化数字0.345678: 345.678‰
7,BigInteger类和BigDecimal类
7.1,BigInteger类
BigInteger表示时大整数类,定义在java.math包下,如果在操作时一个整形数据已经超过了整数的最大类型长度long,数据无法装入,此时可以使用BigInteger类进行操作。
|--------------------------------------------------------------|--------|--------------------------------|
| 方法 | 类型 | 描述 |
| public BigInteger(String val) | 构造 | 将一个字符串变为BigInteger类型的数据 |
| public BigInteger add(BigInteger val) | 普通 | 加法 |
| public BigInteger substract(BigInteger val) | 普通 | 减法 |
| public BigInteger multiply(BigInteger val) | 普通 | 乘法 |
| public BigInteger divide(BigInteger val) | 普通 | 除法 |
| public BigInteger max(BigInteger val) | 普通 | 返回两个数字中的最大值 |
| public BigInteger min(BigInteger val) | 普通 | 返回两个数据中的最小值 |
| public BigInteger[] divideAndRemainder(BigInteger val) | 普通 | 除法操作,数组的第一个元素为除法的商,第二个元素为除法余数。 |BigInteger bi1 = new BigInteger("123456789"); BigInteger bi2 = new BigInteger("987654321"); System.out.println("加法操作:"+bi1.add(bi2)); System.out.println("减法操作:"+bi1.subtract(bi2)); System.out.println("乘法操作:"+bi1.multiply(bi2)); System.out.println("除法操作:"+bi1.divide(bi2)); System.out.println("最大数:"+bi1.max(bi2)); BigInteger result[] = bi2.divideAndRemainder(bi1); System.out.println("商是:"+result[0]+" 余数是:"+result[1]); ================================================== 加法操作:1111111110 减法操作:-864197532 乘法操作:121932631112635269 除法操作:0 最大数:987654321 商是:8 余数是:9
7.2,BigDecimal类
对于不需要任何准确计算精度的数字可以直接使用float或double,但是如果需要精确的计算结果,则必须使用BigDecimal类,而且使用BigDecimal类也可以进行大数的操作。
|--------------------------------------------|--------|------------------------------|
| 方法 | 类型 | 描述 |
| public BigDecimal(double val) | 构造 | 将double表示形式转换为BigDecimal |
| public BigDecimal(int val) | 构造 | 将int表示形式转换为BigDecimal |
| public BigDecimal(String val) | 构造 | 将字符串表示形式转换为BigDecimal |
| public BigDecimal(BigDecimal augend) | 普通 | 加法 |
| public BigDecimal subtract(BigDecimal) | 普通 | 减法 |
| public BigDecimal multiply | 普通 | 乘法 |
| public BigDecimal divide(BigDecimal) | 普通 | 除法 |BigDecimal bi1 = new BigDecimal("123456789.123"); BigDecimal bi2 = new BigDecimal(11.1); System.out.println("加法操作:"+bi1.add(bi2)); System.out.println("减法操作:"+bi1.subtract(bi2)); System.out.println("乘法操作:"+bi1.multiply(bi2)); System.out.println("除法操作:"+bi1.divide(bi2,3,BigDecimal.ROUND_HALF_UP)); //如果用BigDecimal做除法的时候一定要在divide方法中传递第二个参数,定义精确到小数点后几位,否则在不整除的情况下,结果是无限循环小数时,就会抛出异常。 ===================================================== 加法操作:123456800.2229999999999996447286321199499070644378662109375 减法操作:123456778.0230000000000003552713678800500929355621337890625 乘法操作:1370370359.2652999561393376541929001177777536213397979736328125 除法操作:11122233.254
8,Comparable比较器和Comparator比较器
8.1,Comparable比较器
Arrays类可以对数组进行排序,排序会根据数值的大小进行排序,同样此方法可以对Object数组进行排序,但是要使用此方法是有要求的,即对象所在的类必须实现Comparable接口,此接口是用于指定对象排序规则的。
public interface Comparable<T>{ public int compareTo(T o) }
**方法返回一个Int类型数据,但是此int的值只能是:**1(表示大于)、0(表示等于)、-1(表示小于)。
排序原理:二叉树排序
class Student implements Comparable<Student>{ private String name; private int age; private float score; public Student(String name, int age, float score) { this.name = name; this.age = age; this.score = score; } public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", score=" + score + '}'; } public int compareTo(Student student){ if (this.score>student.score){ return -1; }else if(this.score> student.score){ return 1; }else{ if(this.age>student.age){ return 1; }else if(this.age<student.age){ return -1; }else{ return 0; } } } } public static void main(String[] args) throws Exception{ Student student[] = {new Student("李四",20,90.0f), new Student("王五",22,90.0f), new Student("赵六",21,70.0f), new Student("孙七",20,70.0f), }; Arrays.sort(student); for (int i=0;i<student.length;i++){ System.out.println(student[i]); } } =============================================================== Student{name='李四', age=20, score=90.0} Student{name='孙七', age=20, score=70.0} Student{name='赵六', age=21, score=70.0} Student{name='王五', age=22, score=90.0}
8.2,Comparator比较器
如果一个类已经开发完成,但是再此类建立的初期并没有实现Comparable接口,此时肯定是无法进行对象排序的,所以为了解决这样的问题,Java定义了另一个比较器的操作接口------Comparator。
class Student implements Comparable<Student>{ private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } public boolean equals(Object obj){ if(this == obj){ return true; } if(!(obj instanceof Student)){ return false; } Student student = (Student)obj; if(student.name.equals(this.name)&&student.age==this.age){ return true; }else{ return false; } } //省略get,set,toString方法 } class StudentComparator implements Comparator<Student> { public int compare(Student s1,Student s2) { if (s1.equals(s2)){ return 0; }else if(s1.getAge()<s2.getAge()){ return 1; }else{ return -1; } } } public class HelloWord { public static void main(String[] args) throws Exception{ Student student[] = {new Student("李四",19), new Student("王五",22), new Student("赵六",21), new Student("孙七",20), }; Arrays.sort(student,new StudentComparator()); for (int i=0;i<student.length;i++){ System.out.println(student[i]); } } } ============================================== Student{name='王五', age=22} Student{name='赵六', age=21} Student{name='孙七', age=20} Student{name='李四', age=19}
9,正则表达式
使用正则表达式可以方便地对数据进行匹配,还可以执行更房价复杂的字符串验证、拆分、替换功能。如果要在程序中应用正则表达式则必须依靠Pattern类(正则规范的编写)与Matcher****类(执行规范,验证是否符合)。
|-------------------|--------------------|---------|--------------------|
| 规范 | 描述 | 规范 | 序号 |
| \\ | 反斜线(\\) | \w | 字母、数字、下划线 |
| \t | 制表符 | \W | 非字母、数字、下划线 |
| \n | 换行 | \s | 所有空白字符(换行、空格符) |
| [abc] | 字符a、b、c | \S | 所有非空白字符 |
| [^abc] | 除了a、b、c之外的任意字符 | ^ | 行的开头 |
| [a-zA-Z0-9] | 由字母、数字组成 | $ | 行的结尾 |
| \d | 数字 | . | 匹配除换行符之外的任意字符 |
| \D | 非数字 | | |数量表示:
|---------|------------------|------------|---------------|
| 规范 | 描述 | 规范 | 描述 |
| X | 必须出现一次 | X{n} | 必须出现n次 |
| X? | 可以出现0次或1次 | X{n,} | 必须出现n次以上 |
| X* | 可以出现0次、1次或多次 | X{n,m} | 必须出现n~m次 |
| X+ | 可以重修按1次或多次 | | |逻辑运算符:
|----------|---------------|---------|---------------|
| 规范 | 描述 | 规范 | 描述 |
| XY | X规范后跟着Y规范 | (X) | 作为一个捕获组规范 |
| X|Y | X规范或Y规范 | | |Pattern类的常用方法:
|-------------------------------------------------|------------------|
| 方法 | 描述 |
| public static Pattern compile(String regex) | 指定正则表达式规则 |
| public Matcher matcher(CharSequence input) | 返回Matcher类实例 |
| public String[] split(CharSequence input) | 字符串拆分 |Matcher类的常用方法:
|--------------------------------------------------|-----------|
| 方法 | 描述 |
| public boolean matches() | 执行验证 |
| public String replaceAll(String replacement) | 字符串替换 |
验证一个字符串是否合法:
String str = "1983-07-27";
String pat = "\d{4}-\d{2}-\d{2}";
Pattern p = Pattern.compile(pat);
Matcher m = p.matcher(str);
if (m.matches()){
System.out.println("日期格式合法!");
}else{
System.out.println("日期格式不合法!");
}日期格式合法!
在程序中"\"字符是需要进行转义的,两个"\\"实际上表示一个"\",所以实际上"\\d"表示的是"\d"。
按照字符串的数字将字符串拆分:
String str = "A1B22C333D4444E55555F";
String pat = "\d+";
Pattern p = Pattern.compile(pat);
String s[] = p.split(str);
for (int x=0;x<s.length;x++){
System.out.print(s[x]+"\t");
}A B C D E F
将数字替换为"-":
String str = "A1B22C333D4444E55555F";
String pat = "\d+";
Pattern p = Pattern.compile(pat);
Matcher m = p.matcher(str);
String newString = m.replaceAll("-");
System.out.println(newString);A-B-C-D-E-F
String类对正则表达式的支持:
|---------------------------------------------------------------|-----------|
| 方法 | 描述 |
| public boolean matches(String regex) | 字符串匹配 |
| public String replaceAll(String regex,String replacement) | 字符串替换 |
| public String[] split(String regex) | 字符串拆分 |String str1 = "A1B22C333D4444E55555F".replace("\\d+","-"); boolean temp = "1983-07-27".matches("\\d{4}-d{2}-\\d{2}"); String s[] = "A1B22C333D4444E55555F".split("\\d+"); System.out.println("字符串替换操作:"+str1); System.out.println("字符串替换验证:"+temp); System.out.println("字符串拆分:"); for (int x = 0;x<s.length;x++){ System.out.print(s[x]+"\t"); } =========================================== 字符串替换操作:A1B22C333D4444E55555F 字符串替换验证:false 字符串拆分: A B C D E F
10,定时调度
10.1,Timer类
Timer类是一个线程设设施,可以用来实现在某一时间或某一段时间安排某一个任务执行一次或定期重复执行。该功能要与TimerTask配合使用。TimerTask类用来实现由TImer安排的一次或重复执行的某一个任务。
每一个Timer对象对应的是一个线程,因此计时器所执行的任务应该迅速完成,否则可能会延迟后续任务的执行,而这些后续的任务就有可能堆在一起,等到该任务完成后才能快速连续执行。
|--------------------------------------------------------------------------------|--------|-----------------------------------------|
| 方法 | 类型 | 描述 |
| public Timer() | 构造 | 用来创建一个计时器并启动该计时器 |
| public void cancel() | 普通 | 用来终止该计时器,并放弃所有已安排的任务,对当前正在执行的任务没有影响 |
| public int purge() | 普通 | 将所有已经取消的任务移除,一般用来释放内存空间 |
| public void schedule(TimerTask task,Date firstTime) | 普通 | 安排一个任务在指定的时间执行,如果已经超过该时间,则立即执行 |
| public void schedule(TimerTask task,Date firstTime,long period) | 普通 | 安排一个任务在指定的时间执行,然后以固定的频率重复执行 |
| public void schedule(TimerTask task,long delay,long period) | 普通 | 安排一个任务在一段时间后执行 |
| public void schedule(TimerTask task,long delay,long period) | 普通 | 安排一个任务在一段时间后执行,然后以固定频率重复执行 |
| public void scheduleAtFixedRate(TimerTask task,Date firstTime,long period) | 普通 | 安排一个任务在指定的时间执行,然后以近似固定频率重复执行 |
| public void scheduleAtFixedRate(TimerTask task,long delay,long period) | 普通 | 安排一个任务在一段时间后执行,然后以近似固定的频率重复执行 |schedule()方法****的执行时间间隔永远是固定的,如果之前出现了延迟的情况,之后也会继续执行设定好的间隔时间来执行。
scheduleAtFixedRate()方法****可以根据出现的延迟时间自动调整下一次间隔的执行时间。
10.2,TimerTask类
要执行具体的热为奴,则必须使用TimerTask类。TimerTask类是hi一个抽象类,如果要使用该类,需要自己建立一个类来继承此类,并实现其中的抽象方法。
|-------------------------------------------|---------------------------------------------------------------------------------|
| 方法 | 描述 |
| public void cancel() | 用来终止此任务,如果该任务只执行一次且还没有执行,则永远不会执行,如果重复执行任务,则之后不会再执行(如果任务正在执行,则执行完后不会再执行) |
| public void run() | 该任务所要执行的具体操作,该方法为引入的接口Runnable中的方法,子类需要覆写此方法。 |
| public long scheduled ExecutionTime() | 返回最近一次要执行该任务的时间(如果正在执行,则返回此任务的执行安排时间),一般再run()方法中调用,用来判断当前是否有足够的时间来执行完成该任务。 |
10.3,定时操作
class MyTask extends TimerTask{ public void run() { SimpleDateFormat sdf = null; sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS"); System.out.println("当前系统时间为:"+sdf.format(new Date())); } } public class HelloWord { public static void main(String[] args) throws Exception{ Timer t = new Timer(); MyTask myTask = new MyTask(); t.schedule(myTask,1000,2000); } } ============================================== 当前系统时间为:2020-12-22 16:20:53:150 当前系统时间为:2020-12-22 16:20:55:074 当前系统时间为:2020-12-22 16:20:57:075 ......