今天的努力只为更好的明天。
String 类 一、概述 String: 
String 声明为 fianl 的,不可被继承。 String 实现了 Serializable 接口,表示字符串是支持序列化的。实现了 Comparable 接口,表示 String 可以进行比较大小。 String 内部定义的 fianl char[ ] value 用于储存字符串数据。 通过字面量的方式(区别new 给一个字符串赋值,此时得到字符串声明在字符串常量池中)。 字符串常量池是不会存储相同的内容(使用 String 类的equals()**比较,返回 true**)的字符串的。 二、String 的不可变性 说明: ① 当对字符串重新赋值,需要重写指定内存中区域赋值,不能使用原有的 value 进行赋值 ② 当对现有的字符串进行操作时,也需要重新指定内存区域的赋值,不能使用原有的 value 进行赋值。 ③ 当调用 String 的 replace()方式修改指定字符串时,也需要重新指定区域赋值,不能使用原有的 value 进行赋值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Test    public void  test () {                String s1 = "abc" ;        String s2 = "abc" ;                System.out.println(s1 == s2);  	System.out.println("*****************" ); 	String s4 = "abc" ; 	String s5 = s4.replace('a' , 'm' ); 	System.out.println(s4); 	System.out.println(s5);    } 
三、String 实例化的不同方式 方式说明: 方式一:通过字面量定义的方式 方式二:通过 new+构造器的方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Test    public void  test1 () {                String  s1 = "JavaEE" ;        String  s2 = "JavaEE" ;                String s3 = new String("javaEE" );        String s4 = new String("javaEE" );        System.out.println(s1 == s2);        System.out.println(s1 == s3);        System.out.println(s1 == s4);        System.out.println(s3 == s4);    } 
图示: 问题: 
1 2 String s = new String("abc" ); 方式创建对象,在内存中创建了几个对象? 	两个:一个是堆空间"new" 结构,另一个是char [] 对应的常量池中的数据:"abc"  
四、字符串拼接方式赋值的对比 说明: 1.常量与常量的拼接结果在常量池,且常量池中不会存在相同的常量 2.只要其中一个是变量,结果就在堆中。 3.如果拼接的结果调用 **intern()**方法,返回值就是在常量池中。
代码示例: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @Test   public void  test2 () {       String s1 = "javaEE" ;       String s2 = "hadoop" ;       String s3 = "javaEEhadoop" ;       String s4 = "javaEE" +"hadoop" ;       String s5 = s1 + "hadoop" ;       String s6 = "javaEE"  + s2;       String s7 = s1 + s2;       System.out.println(s3 == s4);       System.out.println(s3 == s5);       System.out.println(s3 == s6);       System.out.println(s3 == s7);       System.out.println(s5 == s6);       System.out.println(s5 == s7);       System.out.println(s6 == s7);       System.out.println("**********************************" );       String s8 = s6.intern();        System.out.println(s3 == s8);    } 
1 2 3 4 5 6 7 8 9 10 11 @Test    public void  test3 () {        String s1 = "javaEEhadoop" ;        String s2 = "javaEE" ;        String s3 = s2 + "hadoop" ;        System.out.println(s1 == s3);        final String s4 = "javaEE" ;         String s5 = s4 + "hadoop" ;        System.out.println(s1 == s5);     } 
五、常用方法 int length():返回字符串的长度: return value.length char charAt(int index): 返回某索引处的字符 return value[index] boolean isEmpty():判断是否是空字符串:return value.length == 0 1 2 3 4 String str = "abc" ; System.out.println(str.length()); System.out.println(str.charAt(2 )); System.out.println(str.isEmpty()); 
String toLowerCase():使用默认语言环境,将 String 中的所字符转换为小写 String toUpperCase():使用默认语言环境,将 String 中的所字符转换为大写 String trim():返回字符串的副本,忽略前导空白和尾部空白 1 2 3 4 5 String str1 = "abcdefg" ; String str2 = "   abcdefg   " ; System.out.println(str1.toLowerCase()); System.out.println(str1.toUpperCase()); System.out.println(str2.trim()); 
boolean equals(Object obj):比较字符串的内容是否相同 boolean equalsIgnoreCase(String anotherString):与 equals 方法类似,忽略大小写 String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+” 1 2 3 4 5 6 7 String str3 = "abcdefg" ; String str4 = "ABCDEFG" ; String str5 = "abcd" ; String str6 = "efg" ; System.out.println(str3.equals(str4));  System.out.println(str3.equalsIgnoreCase(str4));  System.out.println(str5.concat(str6)); 
int compareTo(String anotherString):比较两个字符串的大小 String substring(int beginIndex):返回一个新的字符串,它是此字符串的从 beginIndex 开始截取到最后的一个子字符串。 String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从 beginIndex 开始截取到 endIndex(不包含)的一个子字符串。 int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始 1 2 3 4 5 6 7 String str7 = "abcdefg" ; String str8 = "abcdefg" ; String str9 = "abcd" ; System.out.println(str7.compareTo(str8));  System.out.println(str7.substring(2 )); System.out.println(str7.substring(0 ,5 ));  System.out.println(str7.indexOf("d" ,0 ));  
boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束 boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始 boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始 1 2 3 4 5 6 7 String str1 = "helloworld" ; boolean b1 = str1.endsWith("rld" ); boolean b2 = str1.startsWith("hel" ); boolean b3 = str1.startsWith("ll" ,2 ); System.out.println(b1);  System.out.println(b2);  System.out.println(b3);  
boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列时,返回 true 1 2 3 String str1 = "helloworld" ; String str2 = "wor" ; System.out.println(str1.contains(str2));  
int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引 1 2 System.out.println(str1.indexOf("ll" ));  System.out.println(str1.indexOf("lo" ,5 )); 
int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引 int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索 1 2 3 String str3 = "hellorworld" ; System.out.println(str3.lastIndexOf("or" ));  System.out.println(str3.lastIndexOf("or" ,2 ));  
注:indexOf 和 lastIndexOf 方法如果未找到都是返回-1 
替换: 
String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所 oldChar 得到的。 String replace(CharSequence target, CharSequence replacement):使用指定的字面值替换序列替换此字符串所匹配字面值目标序列的子字符串。 String replaceAll(String regex, String replacement):使用给定的 replacement 替换此字符串所匹配给定的正则表达式的子字符串。 String replaceFirst(String regex, String replacement):使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。 1 2 3 4 5 6 7 8 9 String str1 = "中国湖南" ;                  String str2 = str1.replace("湖南" ,"湖北" );         System.out.println(str2);          System.out.println("*********************************************" );                  String str3 = "12hello34world5java7891mysql456" ;         String str4 = str3.replaceAll("\\d+" , "," ).replaceAll("^,|,$" , "" );         System.out.println(str4);  
匹配: 
boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。 1 2 3 4 String str5 = "12345" ;              boolean matches = str5.matches("\\d+" );       System.out.println(matches);  
切片: 
String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。 String[] split(String regex, int limit):根据匹配给定的正则表达式来拆分此字符串,最多不超过 limit 个,如果超过了,剩下的全部都放到最后一个元素中。 1 2 3 4 5 6 7 8 9 10 11 String str6 = "hello|world|java" ;       String[] strs = str6.split("\\|" );       for  (int  i = 0 ; i < strs.length; i++) {           System.out.println(strs[i]);        }       System.out.println();       String str7 = "hello.world.java" ;       String[] strs2 = str7.split("\\." );       for  (int  i = 0 ; i < strs.length; i++) {           System.out.println(strs2[i]);        } 
String 与其他结构的替换 ① 与基本的数据类型、包装类之间的装换String  ----  基本数据类型、包装类:调用包装类的静态方法:parse**XXX**(str)
基本数据类型、包装类 — String:调用 String 重载的 valueof(XXX )
 代码示例 
1 2 3 4 5 6 7 public void  test1 () {         String str = "123" ;         int  num = Integer.parseInt(str);         System.out.println(num);         String str1 = String.valueOf(num);         System.out.println(str1);     } 
String ====》char[ ]: 调用 String 的 toCharArray(); char[ ] ===》 String :调用 String 的构造器
代码示例 
1 2 3 4 5 6 7 8 9 10 11 12 13  public void  test2 () {         String str = "abc123" ;         char [] ch = str.toCharArray();        for (int  i = 0 ; i < ch.length; i++){            System.out.println(ch[i]);        }         System.out.println("***************************" );        char [] arr = new char []{'h' ,'l' ,'l' };        String str2 = new String(arr);         System.out.println(str2);     } 
编码:String ===》 byte[ ]:调用 String 的 getBytes(); 解码:byte[ ] ===》 String :调用 String 的构造器 编码:字符串 ===》 字节(二进制) 解码:编码的逆过程,字节 ===》 字符串 说明:解码时,要求解码的使用的字符集必须与编码的字符集一致,否则会出现乱码。
代码示例: 
1 2 3 4 5 6 7 public void  test3 ()  throws UnsupportedEncodingException {        String str = "abc" ;        byte[] bytes = str.getBytes();         System.out.println(bytes);        byte[] gbks = str.getBytes("gbk" );        System.out.println(Arrays.toString(gbks));    } 
运行结果: 补充:  与 StringBuffer、StringBuilder 之间的转换 String === 》 StringBuffer、StringBuilder:调用 StringBuffer、StringBuilder 构造器; StringBuffer、StringBuilder ===》 String: ① 调用 String 构造器 ② StringBuffer、StringBuilder 的 toString();
JVM 中字符串常量池存放位置说明: JDK 1.6: (jdk 6.0 , java 6.0):字符串常量池存储在方法区( 永久区)  JDK 1.7: 字符串常量池存储在堆空间  JDK 1.8: 字符串常量池存储在方法区(云空间 )
StringBuffer、StringBuilder 一、String、String、StringBuilder 三者的对比 1 2 3 String:不可变的字符序列:底层使用char [] 储存 StringBuffer: 可变的字符序列:线程安全的,效率低:底层使用char []存储 StringBuilder: 可变的字符序列:jdk5.0 :新增的,线程不安全,效率高;底层使用char [] 存储 
可变类型:
 比如列表:列表名(或称为列表引用)指向堆空间中的一个列表。列表引用当中存储的内容为地址,可以指向堆内存中的具体对象.
一方面,该列表可以保证在地址不变的前提下,改变列表内容;另一方面,该引用也可以直接指向堆空间中的另外一个列表..
不可变序列:
比如数字、字符、(元祖):对于基础数据类型,变量地址即变量本身,所以值发生变化了,内存地址就一定也变了。
比如字符串:被称为不可变的字符序列,每个字符底层均有规范的Unicode码对应,内存规定无法对单一的一个字符进行修改,要修改字符串必须重新指向一个全新的字符串
二、StringBuffer 与 StringBuilder 的内存解析 1 2 3 4 5 6 7 8 9 10 以Stringuffer为例: String str = new String(); String str1 = new String("abc" ); StringBuffer sb1 = new StringBuffer(); System.out.println(sb1.length()); sb1.append('a' ); sb1.append('b' ); StringBuffer sb2 = new StringBuffer("abc" ); 
扩容问题:如果添加的数组底层数组盛不下,那就需要扩容底层的数组 默认的情况,扩容为原来的 2 倍+2;同时将原来的数组复制到新数组中。 在开发中优先使用:StringBuffer、StringBuilder
三、对比 String、StringBuffer 、StringBuilder 三者的执行效率 从高到低排序:StringBuiler > StringBuffer > String
四、StringBuffer、StringBuilder 中常用的方法 1 2 3 4 5 6 7 增:oppend(XXX) 删:delete(int  start, int  end) 改:setCharAt(int  n , char  ch) / replance(int  start, int  end , Sting str) 查:charAt(int  n) 插: insert(int  offset , XXX); 长度:Lenght(); *遍历:for () + charAt() / toString() 
JDK 8 之前日期时间 API 一、获取系统之前当前时间 System 类中的 CurrentTimeMills()
1 2 3 4 long  time = Sysem.cuurenTimeMillis()System.out.println(time); 
二、java.util.Date 类与 java.sql.Date 类 1 2 3 4 5 6 7 8 9 10 11 java.util.Date类 	|---java.sql.Date类 1. 两个构造器的使用	>构造器一:Date()创建一个对应当前时间的Date对象 	>构造器二:创建指定毫秒数的Date对象 2. 两个方法的使用	>toString() 显示当前的年、月、日、分、秒 	>getTime() 获取当前Date对象对应的毫秒数。(时间戳) 3. java.sql.Date对应着数据中日期类型的变量	> 实例化 	> 将java.util.Date 转为 java.sql.Date 
代码示例: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 @Test    public void  test1 () {        long  time = System.currentTimeMillis();        System.out.println(time);    }    @Test    public void  test2 () {                Date date = new Date();        System.out.println(date.toString());         System.out.println(date.getTime());     }    @Test    public void  test3 () {                Date date = new Date(1592039273009L );        System.out.println(date.toString());         System.out.println("***********************" );                java.sql.Date date1 = new java.sql.Date(1592039273009L );        System.out.println(date1);     }    @Test        public void  test4 () {                Date date = new java.sql.Date(1592039273009L );        java.sql.Date date1 = (java.sql.Date) date;                Date date2 = new Date();        java.sql.Date date3 = new java.sql.Date(date2.getTime());    } 
三、java.text.SimpleDateFormat 类 1 2 3 4 5 simpleDateFormat 对日期Date类的格式化和解析 1. 两个操作	1.1  格式化:日期 --> 字符串 	1.2  解析: 格式化的逆过程,字符串 --> 日期 2. SimpleDateFormat
1 2 3 4 5 6 7 8 9 10 11 12 13 14  @Test     public void  test5 ()  throws ParseException {         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd  hh:mm aaa" );                  Date date = new Date();         String format = sdf.format(date);         System.out.println(format);                            Date parse = sdf.parse("2020-06-13  05:23 下午" );         System.out.println(parse);      } 
四、Calendar 类:日历类、抽象类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 @Test     public void  test6 () {                                    Calendar calendar = Calendar.getInstance();                           int  days = calendar.get(Calendar.DAY_OF_MONTH);         System.out.println(days);         System.out.println(calendar.get(Calendar.DAY_OF_YEAR));                   calendar.set (Calendar.DAY_OF_MONTH,22 );         int  days1 = calendar.get(Calendar.DAY_OF_MONTH);         System.out.println(days1);                   calendar.add(Calendar.DAY_OF_MONTH,-3 );         days = calendar.get(Calendar.DAY_OF_MONTH);         System.out.println(days);                   Date time = calendar.getTime();         System.out.println(time);                  Date date = new Date();         calendar.setTime(date);         days = calendar.get(Calendar.DAY_OF_MONTH);         System.out.println(days);      } 
JDK8 中新日期时间 API 一、日期时间的迭代 第一代:jdk 1.0 Date 类 第二代:jdk 1.1 Calender 类,一定的程度上替代了 Date 类 第三代:jdk 1.8 提出了新的一套 API
二、前两代存在的问题举例: 可变性:像时间和日期这样的类应该是吧不可变的。 偏移性:Date 中的年份是从 1900 年开始的,月份是从 0 开始的。 格式化:格式话只对 Date 有用,calender 则不行。 此外,它们也不是线程安全的,不能处理闰秒等。
三、java 8 中新的日期时间 API 涉及到的包 
四、本地日期、本地时间、本地日期时间的使用:LocalDate/LocalTime/LocalDateTime 一、说明① 分别表示使用 ISO-8601 日历系统的日期、时间、和时间。它们提供了简单的本地时间信息,也不包含当前的时间信息,也不包含与时区相关的信息。 ② LocalDatetime 相较于 LocalDate、LocalTIme,使用频率高 ③ 类似于 Calender
 二、常用方法 五 时间点:Instant 一、说明
① 时间线上的一个瞬时点,概念上讲。它只是简单的表示自 1970 年 1 月 1 日 0 时 0 秒(UTC 开始的秒数) ② 类似于 java.util.Date 类
二、常用方法
① 格式化或解析日期、时间 ② 类似于 SimpleDateFormat
预定义的标准格式,如:ISO_LOCAL_DATE_TIME; ISO_LOCAL_DATE;ISO_DATE;ISO_LOCAL_TIME  本地相关的格式:如:ofLocalizedDateTime(FormatStyle.LONG)  自定义的格式:如:ofPattern(“yyyy-MM-dd hh:mm:ss”) 
② 常用方法
1 2 3 4 5 6 7 8 9 10 11 public void  test1 () {      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss" );            String str = formatter.format(LocalDateTime.now());      System.out.println(str);             TemporalAccessor accessor = formatter.parse("2020-06-20 03:38:37" );      System.out.println(accessor);    } 
七、其他 带时区的日期时间:ZonedDateTime / ZoneId 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28   @Test   public void  test3 () {            Set<String> zoneIds = ZoneId.getAvailableZoneIds();      for  (String s : zoneIds) {         System.out.println(s);      }      System.out.println("***********************" );      LocalDateTime localDateTime = LocalDateTime.now(ZoneId.of("Asia/Tokyo" ));      System.out.println(localDateTime);    }      @Test   public void  test4 () {            ZonedDateTime now = ZonedDateTime.now();      System.out.println(now);             ZonedDateTime zonedDateTiem = ZonedDateTime.now(ZoneId.of("Asia/Shanghai" ));      System.out.println(zonedDateTiem);   } 
时间间隔:Duration–用于计算两个“时间”间隔,以秒和纳秒为基准 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public void  test5 () {      LocalTime localTime = LocalTime.now();      LocalTime localTime2 = LocalTime.of(15 , 23 , 32 );            Duration between = Duration.between(localTime, localTime2);      System.out.println(between);      System.out.println(between.getSeconds());      System.out.println(between.getNano());      LocalDateTime localdatetime = LocalDateTime.of(2016 , 6 , 12 , 15 , 23 , 32 );      LocalDateTime localdatetime1 = LocalDateTime.of(2017 , 6 , 12 , 15 , 23 , 32 );      Duration between1 = Duration.between(localdatetime, localdatetime1);      System.out.println(between1.toDays());    } 
日期间隔:Period –用于计算两个“日期”间隔,以年、月、日衡量 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public void  test6 () {       LocalDate localdate = LocalDate.now();       LocalDate localdate1 = LocalDate.of(2028 , 3 , 18 );       Period period = Period.between(localdate, localdate1);       System.out.println(period);        System.out.println(period.getYears());        System.out.println(period.getMonths());        System.out.println(period.getDays());        Period period1 = period.withYears(2 );       System.out.println(period1);     } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public void  test7 () {            TemporalAdjuster temporalAdjuster = TemporalAdjusters.next(DayOfWeek.SUNDAY);      LocalDateTime localDateTime = LocalDateTime.now().with(temporalAdjuster);      System.out.println(localDateTime);             LocalDate localDate = LocalDate.now().with(new TemporalAdjuster() {         @Override         public Temporal adjustInto(Temporal temporal) {            LocalDate date = (LocalDate) temporal;            if  (date.getDayOfWeek().equals(DayOfWeek.FRIDAY)) {               return  date.plusDays(3 );            } else  if  (date.getDayOfWeek().equals(DayOfWeek.SATURDAY)) {               return  date.plusDays(2 );            } else  {               return  date.plusDays(1 );            }         }      });      System.out.println("下一个工作日是:" +localDate);   } 
Java 比较器 一、java 比较器的使用背景 ① Java 中的对象,正常情况下,只能进行比较: == 或 != ,不能使用 > 或 < 但是在开发场景中,我们需要对多个对象进行排序,言外之意,就需要比较对象的大小。使用两个接口中的任何一个: Comparable  或 Compartor 
二、自然排序:使用 comparable 接口 说明① 像 String、包装类等实现了 Comparable 接口,重写了 comparaTo(obj)方法,给出了比较两个对象大小的方式。 ② String、包装类重写了 comparaTo()的规则: 如果当前的对象 this 大于形参对象 obj,则返回正整数. 如果当前对象 this 小于形参 obj,则返回负整数 如果当前对象 this 等于形对象 obj,则返回零。 ③ 对于自定义类来说,如果需要排序,我们可以自定义类实现 Comparablej 接口,重写 comparaTo(obj)方法。在 comparaTo()方法中指明如何排序
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class  Goods  implements  Comparable {     private Sting name;     private double  price;            @Override     public int  compareTo (Object o)  {         if (o instanceof Goods){             Goods goods = (Goods)o;                          if (this.price > goods.price){                 return  1 ;             }else  if (this.price < goods.price){                 return  -1 ;             }else {                return  -this.name.compareTo(goods.name);             }                      }         throw new RuntimeException("传入的数据类型不一致!" );     } }     } } 
三、定制排序:使用 Comparator 接口 说明: 
① 背景:
当元素的类型没实现 java.lang.comparable 接口而又不方便修改代码,或实现了 java.lang.Comparable 接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象类排序
② 重写 comparator(Object o1, Object o2)方法,比较 o1 和 o2 的大小:
重写方法返回正整数,则表示 o1 大于 o2 如果返回 0,表示相等 返回负整数,表示 o1 小于 o2
代码示例: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Comparator com = 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;             if (g1.getName().equals(g2.getName())){                 return  -Double.compare(g1.getPrice(),g2.getPrice());             }else {                 return  g1.getName().compareTo(g2.getName());             }         }         throw new RuntimeException("输入的数据类型不一致" );     } } 
1 2 3 Arrays.sort(goods,com); Collections.sort(coll,com); new TreeSet(com); 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27  public void  test3 () {         Goods[] arr = new Goods[6 ];         arr[0 ] = new Goods("lenovoMouse" ,34.0 );         arr[1 ] = new Goods("dellMouse" ,43.0 );         arr[2 ] = new Goods("xiaomiMouse" ,12.0 );         arr[3 ] = new Goods("huaweiMouse" ,65.0 );         arr[4 ] = new Goods("huaweiMouse" ,224.0 );         arr[5 ] = new Goods("microsoftMouse" ,43.0 );         Arrays.sort(arr);         System.out.println("Comparable排序" +Arrays.toString(arr));                 Arrays.sort(arr, new Comparator<Goods>() {             @Override             public int  compare(Goods o1, Goods o2) {                             if (o1.getName().equals(o2.getName())){                    return  -Double.compare(o1.getPrice(),o2.getPrice());                }else {                    return  o1.getName().compareTo(o2.getName());                }             }         });         System.out.println("Comparator:" +Arrays.toString(arr));     } } 
其他类 一、System 类 ① System 类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于 java.lang 包。 ② 由于该类的构造器是 private 的,所以无法创建该类的对象,也就是无法实例化该类。其内部的成员变量和成员方法都是 static 的,所以也可以很方便的进行调用。
1 2 3 4 native long  currentTimeMillis ()  void  exit (int  status) void  gc () String getProperty (String key)  
二、Math 类 1 java.lang.Math提供了一系列静态方法用于科学计算。其方法的参数和返回值类型一般为double 型。 
三、BigInteger 类、BigDecimal 类 说明: 
① java.math 包的 BigInteger 可以表示不可变的任意精度的整数。 ② 要求数字精度比较高,用到 java.math.BigDecimal 类
1 2 3 4 5 6 7 8 9 10 11 12 public class  BigIntegerTest  {     @Test     public void  test1 () {         BigInteger bi = new BigInteger("12323443544535" );         BigDecimal bd = new BigDecimal("233434.35445" );         BigDecimal bd2 = new BigDecimal("2113" );         System.out.println(bi);          System.out.println(bd.divide(bd2,BigDecimal.ROUND_HALF_UP));          System.out.println(bd.divide(bd2,15 ,BigDecimal.ROUND_HALF_UP));      } }