目录
一、字符串相关的类(String类及常用方法、StringBuffer、StringBuilder)
二、JDK8之前的日期时间API(System静态方法、Date类、Calendar类、SimpleDateFormat类)
三、JDK8中新日期时间API(LocalDate、LocalTime、LocalDateTime、Instant、DateTimeFormatter、其它类)
四、Java比较器(Comparable接口、Comparator接口)
五、System类
六、、Math类
七、BigInteger与BigDecimal(了解)
String:字符串,使用一对""引起来表示。
1.String声明为final的,不可被继承
2.String实现了Serializable接口:表示字符串是支持序列化的。
实现了Comparable接口:表示String可以比较大小
3.String内部定义了final char[] value用于存储字符串数据
4.String:代表不可变的字符序列。简称:不可变性。
体现:1.当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值。
2. 当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。
3. 当调用String的replace()方法修改指定字符或字符串时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。
4.通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中。
5.字符串常量池中是不会存储相同内容的字符串的。
演示示例:
@Test public void test1(){ String s1 = "abc";//字面量的定义方式 String s2 = "abc"; s1 = "hello"; System.out.println(s1 == s2);//比较s1和s2的地址值 System.out.println(s1);//hello System.out.println(s2);//abc System.out.println("*****************"); String s3 = "abc"; s3 += "def"; System.out.println(s3);//abcdef System.out.println(s2); System.out.println("*****************"); String s4 = "abc"; String s5 = s4.replace('a', 'm'); System.out.println(s4);//abc System.out.println(s5);//mbc } }
String的实例化方式:
方式一:通过字面量定义的方式
方式二:通过new + 构造器的方式
面试题:String s = new String("abc");方式创建对象,在内存中创建了几个对象?
两个:一个是堆空间中new结构,另一个是char[]对应的常量池中的数据:"abc"
演示示例:
@Test public void test2(){ //通过字面量定义的方式:此时的s1和s2的数据javaEE声明在方法区中的字符串常量池中。 String s1 = "javaEE"; String s2 = "javaEE"; //通过new + 构造器的方式:此时的s3和s4保存的地址值,是数据在堆空间中开辟空间以后对应的地址值。 String s3 = new String("javaEE"); String s4 = new String("javaEE"); System.out.println(s1 == s2);//true System.out.println(s1 == s3);//false System.out.println(s1 == s4);//false System.out.println(s3 == s4);//false System.out.println("***********************"); Person p1 = new Person("Tom",12); Person p2 = new Person("Tom",12); System.out.println(p1.name.equals(p2.name));//true System.out.println(p1.name == p2.name);//true p1.name = "Jerry"; System.out.println(p2.name);//Tom }
public class Person { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } public Person() { } }
结论:
1.常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
2.只要其中有一个是变量,结果就在堆中。
3.如果拼接的结果调用intern()方法,返回值就在常量池中
演示示例:
@Test public void test3(){ 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);//true System.out.println(s3 == s5);//false System.out.println(s3 == s6);//false System.out.println(s3 == s7);//false System.out.println(s5 == s6);//false System.out.println(s5 == s7);//false System.out.println(s6 == s7);//false String s8 = s6.intern();//返回值得到的s8使用的常量值中已经存在的“javaEEhadoop” System.out.println(s3 == s8);//true }
@Test public void test4(){ String s1 = "javaEEhadoop"; String s2 = "javaEE"; String s3 = s2 + "hadoop"; System.out.println(s1 == s3);//false final String s4 = "javaEE";//s4:常量 String s5 = s4 + "hadoop"; System.out.println(s1 == s5);//true }
演示示例:@Test public void test1() { String s1 = "HelloWorld"; System.out.println(s1.length()); System.out.println(s1.charAt(0)); System.out.println(s1.charAt(9)); // System.out.println(s1.charAt(10)); // s1 = ""; System.out.println(s1.isEmpty()); String s2 = s1.toLowerCase(); System.out.println(s1);//s1不可变的,仍然为原来的字符串 System.out.println(s2);//改成小写以后的字符串 String s3 = " he llo world "; String s4 = s3.trim(); System.out.println("-----" + s3 + "-----"); System.out.println("-----" + s4 + "-----"); } }
@Test public void test2() { String s1 = "HelloWorld"; String s2 = "helloworld"; System.out.println(s1.equals(s2)); System.out.println(s1.equalsIgnoreCase(s2)); String s3 = "abc"; String s4 = s3.concat("def"); System.out.println(s4); String s5 = "abc"; String s6 = new String("abe"); System.out.println(s5.compareTo(s6));//涉及到字符串排序 String s7 = "北京尚硅谷教育"; String s8 = s7.substring(2); System.out.println(s7); System.out.println(s8); String s9 = s7.substring(2, 5); System.out.println(s9); }
String常用方法2
>boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
> boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
> boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始
演示示例:什么情况下,indexOf(str)和lastIndexOf(str)返回值相同?@Test public void test3(){ String str1 = "hellowworld"; boolean b1 = str1.endsWith("rld"); System.out.println(b1); boolean b2 = str1.startsWith("He"); System.out.println(b2); boolean b3 = str1.startsWith("ll",2); System.out.println(b3); String str2 = "wor"; System.out.println(str1.contains(str2)); System.out.println(str1.indexOf("lol")); System.out.println(str1.indexOf("lo",5)); String str3 = "hellorworld"; System.out.println(str3.lastIndexOf("or")); System.out.println(str3.lastIndexOf("or",6));
情况一:存在唯一的一个str。 情况二:不存在str
演示示例:@Test public void test4(){ String str1 = "北京尚硅谷教育北京"; String str2 = str1.replace('北', '东'); System.out.println(str1); System.out.println(str2); String str3 = str1.replace("北京", "上海"); System.out.println(str3); System.out.println("*************************"); String str = "12hello34world5java7891mysql456"; //把字符串中的数字替换成,,如果结果中开头和结尾有,的话去掉 String string = str.replaceAll("\\d+", ",").replaceAll("^,|,$", ""); System.out.println(string); System.out.println("*************************"); str = "12345"; //判断str字符串中是否全部有数字组成,即有1-n个数字组成 boolean matches = str.matches("\\d+"); System.out.println(matches); String tel = "0571-4534289"; //判断这是否是一个杭州的固定电话 boolean result = tel.matches("0571-\\d{7,8}"); System.out.println(result); System.out.println("*************************"); str = "hello|world|java"; String[] strs = str.split("\\|"); for (int i = 0; i < strs.length; i++) { System.out.println(strs[i]); } System.out.println(); str2 = "hello.world.java"; String[] strs2 = str2.split("\\."); for (int i = 0; i < strs2.length; i++) { System.out.println(strs2[i]); } }
面试题:(考察涉及字符串的值传递)
public class StringExer { String str = new String("good"); char[] ch = { 't', 'e', 's', 't' }; public void change(String str, char ch[]) { str = "test ok"; ch[0] = 'b'; } public static void main(String[] args) { StringExer ex = new StringExer(); ex.change(ex.str, ex.ch); System.out.println(ex.str);//good System.out.println(ex.ch);//best } }
复习:
1、String 与基本数据类型、包装类之间的转换:
String --> 基本数据类型、包装类:调用包装类的静态方法:parseXxx(str)
基本数据类型、包装类 --> String:调用String重载的valueOf(xxx)
@Test public void test1(){ String str1 = "123"; // int num = (int)str1;//错误的 int num = Integer.parseInt(str1); String str2 = String.valueOf(num);//"123" String str3 = num + ""; System.out.println(str1 == str3); }
2、String 与 char[]之间的转换:
String --> char[]:调用String的toCharArray()
char[] --> String:调用String的构造器
@Test public void test2(){ String str1 = "abc123"; //题目: a21cb3 char[] charArray = str1.toCharArray(); for (int i = 0; i < charArray.length; i++) { System.out.println(charArray[i]); } char[] arr = new char[]{'h','e','l','l','o'}; String str2 = new String(arr); System.out.println(str2); }
3、 String 与 byte[]之间的转换:
编码:String --> byte[]:调用String的getBytes()
解码:byte[] --> String:调用String的构造器
编码:字符串 -->字节 (看得懂 --->看不懂的二进制数据)
解码:编码的逆过程,字节 --> 字符串 (看不懂的二进制数据 ---> 看得懂)
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致,否则会出现乱码。
@Test public void test3() throws UnsupportedEncodingException { String str1 = "abc123中国"; byte[] bytes = str1.getBytes();//使用默认的字符集,进行编码。 System.out.println(Arrays.toString(bytes)); byte[] gbks = str1.getBytes("gbk");//使用gbk字符集进行编码。 System.out.println(Arrays.toString(gbks)); System.out.println("******************"); String str2 = new String(bytes);//使用默认的字符集,进行解码。 System.out.println(str2); String str3 = new String(gbks); System.out.println(str3);//出现乱码。原因:编码集和解码集不一致! String str4 = new String(gbks, "gbk"); System.out.println(str4);//没有出现乱码。原因:编码集和解码集一致! }
字符串相关的类:StingBuffer和StringBuilder:
String、StringBuffer、StringBuilder三者的异同?
String:不可变的字符序列;底层使用char[]存储
StringBuffer:可变的字符序列;线程安全的,效率低;底层使用char[]存储
StringBuilder: 可变的字符序列;jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储
StringBuffer类:
》StringBuffer类不同于String,其对象必须使用构造器生成。有三个构造器:
>StringBuffer():初始容量为16的字符串缓冲区
>StringBuffer(int size):构造指定容量的字符串缓冲区
>StringBuffer(String str):将内容初始化为指定字符串内容
源码分析:
String str = new String();//char[] value = new char[0];
String str1 = new String("abc");//char[] value = new char[]{'a','b','c'};StringBuffer sb1 = new StringBuffer();//char[] value = new char[16];底层创建了一个长度是16的数组。
System.out.println(sb1.length());//0
sb1.append('a');//value[0] = 'a';
sb1.append('b');//value[1] = 'b';StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length() + 16];
//问题1. System.out.println(sb2.length());//3
//问题2. 扩容问题:如果要添加的数据底层数组盛不下了,那就需要扩容底层的数组。
默认情况下,扩容为原来容量的2倍 + 2,同时将原有数组中的元素复制到新的数组中。指导意义:开发中建议大家使用:StringBuffer(int capacity) 或 StringBuilder(int capacity)
StringBuffer类的常用方法:
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 int indexOf(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()
演示示例:
@Test public void test2(){ StringBuffer s1 = new StringBuffer("abc"); s1.append(1); s1.append('1'); System.out.println(s1); // s1.delete(2,4); // s1.replace(2,4,"hello"); // s1.insert(2,false); // s1.reverse(); String s2 = s1.substring(1, 3); System.out.println(s1); System.out.println(s1.length()); System.out.println(s2); }
@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)); }
【面试题】程序输出:String str = null ;StringBuffer sb = new StringBuffer();sb .append( str );System. out .println( sb .length()); //System. out .println( sb ); //StringBuffer sb1 = new StringBuffer( str );System. out .println( sb1 ); //public class IDEADebug { @Test public void testStringBuffer(){ String str = null; StringBuffer sb = new StringBuffer(); sb.append(str);// System.out.println(sb.length());//4 System.out.println(sb);//"null" StringBuffer sb1 = new StringBuffer(str);//抛异常NullPointerException System.out.println(sb1);// }
面试题:
public class exerTest { public static void main(String[] args) { String a = "123"; String b = "123"; String c = new String("123"); String d = new String("123"); System.out.println(a.equals(b));//true System.out.println(a == b);//true System.out.println(c.equals(d));//true System.out.println(c == d);//false System.out.println(a.equals(c));//true System.out.println(a == c);//false } }
练习 5 :常见算法题目1. 模拟一个 trim 方法,去除字符串两端的空格2. 将一个字符串进行反转。将字符串中指定部分进行反转。比如 “ab cdef g” 反转为 ”ab fedc g”①方式一:转换为char[]public class StringDemo { public String reverse(String str,int startIndex,int endIndex){ if(str != null){ char[] arr = str.toCharArray(); for(int x = startIndex,y = endIndex;x < y;x++,y--){ char temp = arr[x]; arr[x] = arr[y]; arr[y] = temp; } return new String(arr); } return null; @Test public void testReverse(){ String str = "abcdefg"; String reverse = reverse2(str, 2, 4); System.out.println(reverse); } }
②方式二:使用String的拼接
public class StringDemo { public String reverse1(String str,int startIndex,int endIndex){ if(str != null){ //第1部分 String reverseStr = str.substring(0,startIndex); //第2部分 for(int i = endIndex;i >= startIndex;i--){ reverseStr += str.charAt(i); } //第3部分 reverseStr += str.substring(endIndex + 1); return reverseStr; } return null; } @Test public void testReverse(){ String str = "abcdefg"; String reverse = reverse1(str, 2, 5); System.out.println(reverse); } }
③方式三:使用StringBuffer/ StringBuilder替换String
public class StringDemo { public String reverse2(String str,int startIndex,int endIndex){ if(str != null){ StringBuilder builder = new StringBuilder(str.length()); //第1部分 builder.append(str.substring(0,startIndex)); //第2部分 for(int i = endIndex;i >= startIndex;i--){ builder.append(str.charAt(i)); } //第3部分 builder.append(str.substring(endIndex + 1)); return builder.toString(); } return null; } @Test public void testReverse(){ String str = "abcdefg"; String reverse = reverse2(str, 2, 5); System.out.println(reverse); } }
3. 获取一个字符串在另一个字符串中出现的次数。比如:获取 “ ab” 在 “abkkcadkabkebfkabkskab” 中出现的次数public int getCount(String mainStr,String subStr){ int mainLength = mainStr.length(); int subLength = subStr.length(); int count = 0; int index = 0; if(mainLength >= subLength){ //方式一: // while((index = mainStr.indexOf(subStr)) != -1){ // count++; // mainStr = mainStr.substring(index + subStr.length()); // } //方式二:对方式一的改进 while((index = mainStr.indexOf(subStr,index)) != -1){ count++; index += subLength; } return count; }else{ return 0; } } @Test public void testGetCount(){ String mainStr = "abkkcadkabkebfkaabkskab"; String subStr = "ab"; int count = getCount(mainStr, subStr); System.out.println(count); } }
4. 获取两个字符串中最大相同子串。比如:str1 = "abcwerthelloyuiodef“;str2 = "cvhellobnm"提示:将短的那个串进行长度依次递减的子串与较长的串比较。public class StringDemo2 { /* 获取两个字符串中最大相同子串。比如: str1 = "abcwerthelloyuiodefabcdef";str2 = "cvhellobnm" 提示:将短的那个串进行长度依次递减的子串与较长的串比较。 */ //前提:两个字符串中只有一个最大相同子串 public String getMaxSameString(String str1,String str2){ if(str1 != null && str2 != null){ String maxStr = (str1.length() >= str2.length())? str1 : str2; String minStr = (str1.length() < str2.length())? str1 : str2; int length = minStr.length(); for(int i = 0;i < length;i++){ for(int x = 0,y = length - i;y <= length;x++,y++){ String subStr = minStr.substring(x,y); if(maxStr.contains(subStr)){ return subStr; } } } } return null; } // 如果存在多个长度相同的最大相同子串 // 此时先返回String[],后面可以用集合中的ArrayList替换,较方便 public String[] getMaxSameString1(String str1, String str2) { if (str1 != null && str2 != null) { StringBuffer sBuffer = new StringBuffer(); String maxString = (str1.length() > str2.length()) ? str1 : str2; String minString = (str1.length() > str2.length()) ? str2 : str1; int len = minString.length(); for (int i = 0; i < len; i++) { for (int x = 0, y = len - i; y <= len; x++, y++) { String subString = minString.substring(x, y); if (maxString.contains(subString)) { sBuffer.append(subString + ","); } } // System.out.println(sBuffer); if (sBuffer.length() != 0) { break; } } String[] split = sBuffer.toString().replaceAll(",$", "").split("\\,"); return split; } return null; } @Test public void testGetMaxSameString(){ String str1 = "abcwerthello1yuiodefabcdef"; String str2 = "cvhello1bnmabcdef"; String[] maxSameStrings = getMaxSameString1(str1, str2); System.out.println(Arrays.toString(maxSameStrings)); } }
5. 对字符串中字符进行自然顺序排序。提示:1 )字符串变成字符数组。2 )对数组排序,选择,冒泡, Arrays.sort();3 )将排序后的数组变成字符串。
1. java.lang.System类
演示示例:@Test public void test1(){ long time = System.currentTimeMillis(); //返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。 //称为时间戳 System.out.println(time); }
2.java.util.Date类
|---java.sql.Date类
1.两个构造器的使用
>构造器一:Date():创建一个对应当前时间的Date对象
>构造器二:创建指定毫秒数的Date对象
2.两个方法的使用
>toString():显示当前的年、月、日、时、分、秒
>getTime():获取当前Date对象对应的毫秒数。(时间戳)
3. java.sql.Date对应着数据库中的日期类型的变量
>如何实例化
>如何将java.util.Date对象转换为java.sql.Date对象
演示示例:
@Test public void test2(){ //构造器一:Date():创建一个对应当前时间的Date对象 Date date1 = new Date(); System.out.println(date1.toString());//Sat Feb 16 16:35:31 GMT+08:00 2019 System.out.println(date1.getTime());//1550306204104 //构造器二:创建指定毫秒数的Date对象 Date date2 = new Date(155030620410L); System.out.println(date2.toString()); //创建java.sql.Date对象 java.sql.Date date3 = new java.sql.Date(35235325345L); System.out.println(date3);//1971-02-13 //如何将java.util.Date对象转换为java.sql.Date对象 //情况一: // Date date4 = new java.sql.Date(2343243242323L); // java.sql.Date date5 = (java.sql.Date) date4; //情况二: Date date6 = new Date(); java.sql.Date date7 = new java.sql.Date(date6.getTime()); }
应用场景:对商品的某个属性(价格、评论数、销量等)进行排序
一、说明:Java中的对象,正常情况下,只能进行比较:== 或 != 。不能使用 > 或 < 的但是在开发场景中,我们需要对多个对象进行排序,言外之意,就需要比较对象的大小。如何实现?使用两个接口中的任何一个:Comparable 或 Comparator
二、Comparable接口与Comparator的使用的对比:
Comparable接口的方式一旦一定,保证Comparable接口实现类的对象在任何位置都可以比较大小。
Comparator接口属于临时性的比较。
Comparable接口的使用举例: 自然排序
1.像String、包装类等实现了Comparable接口,重写了compareTo(obj)方法,给出了比较两个对象大小的方式。
2.像String、包装类重写compareTo()方法以后,进行了从小到大的排列
3. 重写compareTo(obj)的规则:
如果当前对象this大于形参对象obj,则返回正整数,
如果当前对象this小于形参对象obj,则返回负整数,
如果当前对象this等于形参对象obj,则返回零。
4. 对于自定义类来说,如果需要排序,我们可以让自定义类实现Comparable接口,重写compareTo(obj)方法。
在compareTo(obj)方法中指明如何排序
Comparator接口的使用:定制排序
1.背景:
当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,
或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,
那么可以考虑使用 Comparator 的对象来排序
2.重写compare(Object o1,Object o2)方法,比较o1和o2的大小:
如果方法返回正整数,则表示o1大于o2;
如果返回0,表示相等;
返回负整数,表示o1小于o2。
演示代码:
public class CompareTest { /* Comparable接口的使用举例: 自然排序 1.像String、包装类等实现了Comparable接口,重写了compareTo(obj)方法,给出了比较两个对象大小的方式。 2.像String、包装类重写compareTo()方法以后,进行了从小到大的排列 3. 重写compareTo(obj)的规则: 如果当前对象this大于形参对象obj,则返回正整数, 如果当前对象this小于形参对象obj,则返回负整数, 如果当前对象this等于形参对象obj,则返回零。 4. 对于自定义类来说,如果需要排序,我们可以让自定义类实现Comparable接口,重写compareTo(obj)方法。 在compareTo(obj)方法中指明如何排序 */ @Test public void test1(){ String[] arr = new String[]{"AA","CC","KK","MM","GG","JJ","DD"}; // Arrays.sort(arr); System.out.println(Arrays.toString(arr)); } @Test public void test2(){ Goods[] arr = new Goods[5]; arr[0] = new Goods("lenovoMouse",34); arr[1] = new Goods("dellMouse",43); arr[2] = new Goods("xiaomiMouse",12); arr[3] = new Goods("huaweiMouse",65); arr[4] = new Goods("microsoftMouse",43); Arrays.sort(arr); System.out.println(Arrays.toString(arr)); } /* Comparator接口的使用:定制排序 1.背景: 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码, 或者实现了java.lang.Comparable接口的排序规则不适合当前的操作, 那么可以考虑使用 Comparator 的对象来排序 2.重写compare(Object o1,Object o2)方法,比较o1和o2的大小: 如果方法返回正整数,则表示o1大于o2; 如果返回0,表示相等; 返回负整数,表示o1小于o2。 */ @Test public void test3(){ String[] arr = new String[]{"AA","CC","KK","MM","GG","JJ","DD"}; Arrays.sort(arr,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); } // return 0; throw new RuntimeException("输入的数据类型不一致"); } }); System.out.println(Arrays.toString(arr)); } @Test public void test4(){ Goods[] arr = new Goods[6]; arr[0] = new Goods("lenovoMouse",34); arr[1] = new Goods("dellMouse",43); arr[2] = new Goods("xiaomiMouse",12); arr[3] = new Goods("huaweiMouse",65); arr[4] = new Goods("huaweiMouse",224); arr[5] = new Goods("microsoftMouse",43); Arrays.sort(arr, 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("输入的数据类型不一致"); } }); System.out.println(Arrays.toString(arr)); } }
/** * 商品类 * @author shkstart * @create 2019 下午 4:52 */ public class Goods implements Comparable{ private String name; private double price; public Goods() { } public Goods(String name, double price) { this.name = name; this.price = 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; } @Override public String toString() { return "Goods{" + "name='" + name + '\'' + ", price=" + price + '}'; } //指明商品比较大小的方式:按照价格从低到高排序,再按照产品名称从高到低排序 @Override public int compareTo(Object o) { // System.out.println("**************"); 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 0; return -this.name.compareTo(goods.name); } //方式二: // return Double.compare(this.price,goods.price); } // return 0; throw new RuntimeException("传入的数据类型不一致!"); } }
演示代码:
@Test public void test1() { String javaVersion = System.getProperty("java.version"); System.out.println("java的version:" + javaVersion); String javaHome = System.getProperty("java.home"); System.out.println("java的home:" + javaHome); String osName = System.getProperty("os.name"); System.out.println("os的name:" + osName); String osVersion = System.getProperty("os.version"); System.out.println("os的version:" + osVersion); String userName = System.getProperty("user.name"); System.out.println("user的name:" + userName); String userHome = System.getProperty("user.home"); System.out.println("user的home:" + userHome); String userDir = System.getProperty("user.dir"); System.out.println("user的dir:" + userDir); }
演示代码:@Test public void test2() { BigInteger bi = new BigInteger("1243324112234324324325235245346567657653"); BigDecimal bd = new BigDecimal("12435.351"); BigDecimal bd2 = new BigDecimal("11"); System.out.println(bi); // System.out.println(bd.divide(bd2)); System.out.println(bd.divide(bd2, BigDecimal.ROUND_HALF_UP)); System.out.println(bd.divide(bd2, 25, BigDecimal.ROUND_HALF_UP)); }