Java学习笔记——Java常用类
Java学习笔记——Java常用类
1 字符串
1.1 String
String是一个final类,代表不可变的字符序列,底层使用char[]存放。一个字符串对象一旦被配置,其内容是不可变的。
1.1.1 内存
String str1 = "JavaEE"; // 字符串常量池 String str2 = "JavaEE"; String str3 = new String("JavaEE"); String str4 = "JavaEE" + "Android"; String str5 = "Android"; String str6 = str1 + str5; str5 = str5 + "Hadoop"; // 字符串常量池新建一个字符串区域,str5改变地址 String str7 = str6.intern(); String str8 = "JavaEEAndroid"; // ==比较引用地址值 System.out.println(str1 == str2); // true System.out.println(str1 == str3); // false System.out.println(str1.equals(str3)); // true System.out.println(str4 == str6); // false ?? System.out.println(str4 == str7); // true System.out.println(str4 == str8); // true final String x = "x"; String y = "y"; String z1 = "xy"; String z2 = x + "y"; String z3 = x + y; System.err.println(z1 == z2); // true System.err.println(z1 == z3); // false
总结:字面量字符串和常量字符串表达式的结果在字符串常量区。 关于intern:
Returns a canonical representation for the string object. A pool of strings, initially empty, is maintained privately by theclass String. When the intern method is invoked, if the pool already contains astring equal to this String object as determined bythe equals(Object) method, then the string from the pool isreturned. Otherwise, this String object is added to thepool and a reference to this String object is returned. It follows that for any two strings s and t, s.intern() == t.intern() is trueif and only if s.equals(t) is true. All literal strings and string-valued constant expressions areinterned. String literals are defined in section 3.10.5 of the The Java™ Language Specification. Returns: a string that has the same contents as this string, but isguaranteed to be from a pool of unique strings. @jls3.10.5 String Literals
1.1.2 常用方法
/* * public int length() public char charAt(int index):返回在指定index位置的字符。index从0开始 public boolean equals(Object anObject) public int compareTo(String anotherString) public int indexOf(String s) public int indexOf(String s ,int startpoint) public int lastIndexOf(String s) public int lastIndexOf(String s ,int startpoint) public boolean startsWith(String prefix) public boolean endsWith(String suffix) public boolean regionMatches(int toffset,String other,int ooffset ,int len): 判断当前字符串从toffset开始的子串与另一个字符串other从ooffset开始的子串是否equals,子串长度为len */ @Test public void test2(){ String str1 = "abcdefghijk"; String str2 = "abcc"; System.out.println(str2.length()); //4 System.out.println(str1.charAt(0)); //a System.out.println(str1.equals(str2)); //false System.out.println(str1.compareTo(str2)); //1 System.out.println(str1.indexOf(c)); //2 System.out.println(str1.indexOf("abc", 1)); //-1 System.out.println(str2.lastIndexOf("c")); //3 System.out.println(str1.startsWith("a")); //true System.out.println(str1.endsWith("jk")); //true System.out.println(str1.regionMatches(0, str2, 0, 3)); // true }
/* * public String substring(int startpoint) public String substring(int start,int end) public String replace(char oldChar,char newChar) public String replaceAll(String old,String new) public String trim() public String concat(String str):Concatenates the specified string to the end of this string. public String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串。 */ @Test public void test3() { String str1 = "hellollo"; String str2 = "hello"; String str3 = str1.substring(2); System.out.println(str3); // llollo System.out.println(str1); // hellollo System.out.println(str1.substring(2, 4)); // ll(左闭右开) String str4 = str1.replace("llo", "aaa"); System.out.println(str4); // heaaaaaa System.out.println(str1); // hellollo System.out.println(" a b ".trim()); // a b System.out.println(str1.concat("aaa").concat(str2)); // hellolloaaahello System.out.println(str1.split("ll")[0]); // he }
1.1.3 类型转换
-
字符串与基本数据类型的相互转换。 // 1.字符串转换为基本数据类型 // Integer包装类的public static int parseInt(String s):可以将由“数字”字符组成的字符串转换为整型。 //类似地,使用java.lang包中的Byte、Short、Long、Float、Double类调相应的类方法可以将由“数字”字符组成的字符串,转化为相应的基本数据类型。 int i = Integer.parseInt("121", 3); // 第二个参数为进制,不加则默认为十进制 boolean b = Boolean.parseBoolean("true"); // 2.基本数据类型转换为字符串 // 调用String类的public String valueOf(int n)可将int型转换为字符串 // 相应的valueOf(byte b)、valueOf(long l)、valueOf(float f)、valueOf(double d)、valueOf(boolean b)可由参数的相应类到字符串的转换 String string = String.valueOf(11); 字符串与字节数组之间的转换。 // 字符串---->字节数组:调用字符串的getBytes() String str = "abcd123"; byte[] b = str.getBytes(); for(int j = 0;j < b.length;j++){ System.out.println((char)b[j]); } // 字节数组---->字符串:调用字符串的构造器 String str3 = new String(b); 字符串与字符数组之间的转换。 // 字符串---->字符数组:调用字符串的toCharArray()或getChars String str4 = "abc123中国人"; char[] c = str4.toCharArray(); // char[] c = new char[str4.length()]; // str4.getChars(0, str4.length(), c, 0); for(int j = 0;j < c.length;j++){ System.out.println(c[j]); } // 字符数组---->字符串:调用字符串的构造器,或String的valueOf方法 String str5 = new String(c); String str6 = new String(c, 0, c.length); String str7 = String.valueOf(c);
总结:封装类的ParseXxx;String类的valueOf,getBytes,toCharArray,getChars;String类的构造器是”万能“的。涉及到字符串与其他类型的转换时,考虑String和封装类的方法。
1.1.4 几个小算法
// 1.模拟一个trim方法,去除字符串两端的空格。 public static String myTrim(String str) { int len = str.length(); int beginIndex = 0; int endIndex = len; while(beginIndex < endIndex && str.charAt(beginIndex) == ) { beginIndex++; } if (beginIndex >= len) { return ""; } while(str.charAt(endIndex - 1) == ) { endIndex--; } return str.substring(beginIndex, endIndex); }
// 2.将一个字符串进行反转。将字符串中指定部分进行反转。比如将“abcdefg”反转为”abfedcg” // 可再使用StringBuffer优化 // 方法一: public static String reverseString(String str, int start, int end) { char[] c = str.toCharArray(); return reverseArray(c, start, end); } public static String reverseArray(char[] c, int start, int end) { for(int i = start, j = end; i < j; i++, j--) { char temp = c[i]; c[i] = c[j]; c[j] = temp; } return new String(c); } // 方法二: public static String reverseString1(String str, int start, int end) { String str1 = str.substring(0, start); for(int i = end; i >= start; i--) { str1 += str.charAt(i); } str1 += str.substring(end + 1); return str1; }
// 3.获取一个字符串在另一个字符串中出现的次数 public static int getTime(String str1, String str2) { int time = 0; int len = str2.length(); int index; while((index = str1.indexOf(str2)) != -1) { time++; str1 = str1.substring(index + len); } return time; }
// 4.获取两个字符串中最大相同子串。 // 提示:将短的那个串进行长度依次递减的子串与较长的串比较。 public static List<String> getMaxSubString(String str1, String str2) { String maxStr = str1; String minStr = str2; if (str1.length() < str2.length()) { maxStr = str2; minStr = str1; } int len = minStr.length(); List<String> list = new ArrayList<String>(); String subStr; for(int i = len; i > 0; i--) { for (int j = 0; j <= len - i; j++) { if(maxStr.contains((subStr = minStr.substring(j, j + i)))) { list.add(subStr); } } if (list.size() != 0) { return list; } } return null; }
// 5.对字符串中字符进行自然顺序排序。 public static String sort(String str) { char[] c = str.toCharArray(); Arrays.sort(c); return new String(c); }
1.2 StringBuffer
java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删。很多方法与String相同,但StingBuffer是可变长度的。StringBuffer是一个容器。
StringBuffer sBuffer = new StringBuffer("123sss"); // 增 sBuffer.append("hello"); sBuffer.insert(3, "hello"); // 删 System.out.println(sBuffer.delete(1, 2)); // 改 sBuffer.setCharAt(0, a); sBuffer.reverse(); // 查 System.out.println(sBuffer.charAt(0));
1.3 StringBuilder
StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且方法也一样。
java.lang.StringBuilder也是可变的字符序列,是jdk5.0新加入的,线程不安全,效率要高于StringBuffer。
/* * 对比String,StringBuffer,StringBuilder三者在添加上的效率: * 效率从高到底: StringBuilde > StringBuffer > String */ @Test public void test3() { String string = ""; StringBuffer sBuffer = new StringBuffer(""); StringBuilder sBuilder = new StringBuilder(""); long startTime; startTime = System.currentTimeMillis(); for (int i = 0; i < 20000; i++) { string = string + i; } System.out.println("String的执行时间: " + (System.currentTimeMillis() - startTime)); startTime = System.currentTimeMillis(); for (int i = 0; i < 20000; i++) { sBuffer.append(i); } System.out.println("StringBuffer的执行时间: " + (System.currentTimeMillis() - startTime)); startTime = System.currentTimeMillis(); for (int i = 0; i < 20000; i++) { sBuilder.append(i); } System.out.println("StringBuilder的执行时间: " + (System.currentTimeMillis() - startTime)); }
String s = "a"; // 创建了一个字符串 s = s + "b"; //实际上原来的"a"字符串对象已经丢弃了,现在又产生了一个字符串s+"b"(也就是"ab")。如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能。
2 日期相关
2.1 java.lang.System
System类提供的public static long currentTimeMillis()用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
计算世界时间的主要标准有:
-
UTC(Universal Time Coordinated) GMT(Greenwich Mean Time) CST(Central Standard Time)
2.2 java.util.Date
表示特定的瞬间,精确到毫秒。
Date date = new Date(); System.out.println(date.toString()); // Mon Feb 18 15:54:20 CST 2019 System.out.println(date.getTime()); // 1550476508130 System.out.println(System.currentTimeMillis()); // 1550476508146 Date date2 = new Date(1550476508146L); System.out.println(date2); // Mon Feb 18 15:55:08 CST 2019
2.3 java.text.SimpleDateFormat
Date类的API不易于国际化,大部分被废弃了,SimpleDateFormat类是一个不与语言环境有关的方式来格式化和解析日期的具体类。
// 1.格式化1(默认) SimpleDateFormat sdf = new SimpleDateFormat(); String str = sdf.format(new Date()); System.out.println(str); // 2019/2/19 上午9:42 // 2.格式化2(自定义) SimpleDateFormat sdf1 = new SimpleDateFormat("hh:mm:ss yy-MM-dd"); String str1 = sdf1.format(new Date()); System.out.println(str1); // 09:42:38 19-02-19 // 3.解析 Date date = sdf.parse(str); System.out.println(date); // Tue Feb 19 09:42:00 CST 2019
// 返回date1与date2之间的天数 // 方式一: public int getDays(String date1, String date2) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date d1 = sdf.parse(date1); Date d2 = sdf.parse(date2); long milliTime = d2.getTime() - d1.getTime(); return (int)(milliTime / 1000 / 3600 / 24) + 1; }
// 方式二: public int getDays2(String date1, String date2) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date d1 = sdf.parse(date1); Date d2 = sdf.parse(date2); int days = 0; int[] daysOfMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int beginYear = d1.getYear() + 1900; int beginMonth = d1.getMonth(); int beginDate = d1.getDate(); int endYear = d2.getYear() + 1900; int endMonth = d2.getMonth(); int endDate = d2.getDate(); daysOfMonth[1] = isLeapYear(beginYear) ? 29 : 28; // 判断2月天数 if (beginYear == endYear) { if (beginMonth == endMonth) { return endDate - beginDate + 1; } // 加上开始月的剩余天数 days += daysOfMonth[beginMonth] - beginDate + 1; // 加上完整月的天数 for(int i = beginMonth + 1; i < endMonth; i++) { days += daysOfMonth[i]; } // 加上最后一个月到结束日期的天数 days += endDate; return days; } // 1.开始年的剩余天数 // 加上开始月的剩余天数 days += daysOfMonth[beginMonth] - beginDate + 1; // 加上剩余月的天数 for(int i = beginMonth + 1; i < 12; i++) { days += daysOfMonth[i]; } // 2.始末年之间的完整年的总天数 for(int i = beginYear + 1; i < endYear; i++) { days += isLeapYear(i) ? 366 : 365; System.out.println(1); } // 3.结束年到结束日期的天数 daysOfMonth[1] = isLeapYear(endYear) ? 29 : 28; // 判断2月天数 // 加上完整月的天数 for (int i = 0; i < endMonth; i++) { days += daysOfMonth[i]; } // 加上最后一个月到结束日期的天数 days += endDate; return days; } // 判断是否为闰年 // 四年一闰;百年不闰,四百年再闰 public boolean isLeapYear(int year) { return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; }
/* * “三天打渔两天晒网” 1990-01-01 XXXX-XX-XX 打渔?晒网? */ @Test public void test3() throws ParseException { String str1 = "1990-01-01"; String str2 = "2014-05-12"; int days = getDays(str1, str2); System.out.println(days); System.out.println(getDays2(str1, str2)); if (days % 5 == 0 || days % 5 == 4) { System.out.println("晒网"); }else { System.out.println("打渔"); } }
2.4 java.util.Calendar
Calendar是一个抽象基类,主用用于完成日期字段之间相互操作的功能。
Calendar calendar = Calendar.getInstance(); int day = calendar.get(Calendar.DAY_OF_MONTH); calendar.add(Calendar.DAY_OF_MONTH, 2); calendar.set(Calendar.DAY_OF_MONTH, 44); Date date = calendar.getTime(); calendar.setTime(date);
3 Math
java.lang.Math提供了一系列静态方法用于科学计算;其方法的参数和返回值类型一般为double型。
-
Fields
-
Methods
常用方法:
-
abs 绝对值 acos,asin,atan,cos,sin,tan 三角函数 sqrt 平方根 pow(double a,doble b) a的b次幂 log 自然对数 exp e为底指数 max(double a,double b) min(double a,double b) random() 返回0.0到1.0的随机数 long round(double a) double型数据a转换为long型(四舍五入) toDegrees(double angrad) 弧度–>角度 toRadians(double angdeg) 角度–>弧度
4 BigInteger
Integer类作为int的包装类,能存储的最大整型值为 2^31-1,BigInteger类的数字范围较Integer类的大得多,可以支持任意精度的整数。
-
Fields
-
Methods
5 BigDecimal
一般的Float类和Double类可以用来做科学计算或工程计算,但在商业计算中,要求数字精度比较高,故用到java.math.BigDecimal类。BigDecimal类支持任何精度的定点数。
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,RoundingMode.HALF_UP)); System.out.println(bd.divide(bd2,15,RoundingMode.HALF_UP));
-
常用方法 public BigDecimal add(BigDecimal augend) public BigDecimal subtract(BigDecimal subtrahend) public BigDecimal multiply(BigDecimal multiplicand) public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
6 疑问
-
字符串字面量赋值给String类型的对象时(不用new),只存了字符串常量池的一个地址,其对象体现在哪里?
以上笔记参考自尚硅谷