Java基础查漏补缺(2)
Java基礎查漏補缺(2)
apache和spring都提供了BeanUtils的深度拷貝工具包
+=具有隱形的強制轉換
object類的equals()方法容易拋出空指針異常
String a=null; /*使用a.equals(b)拋出異常 優化方法1,若b為常量,即a.equals("test") 此時調用"test".equals(a)可避免空指針錯誤 優化方法2,使用Objects工具類:java.util.Objects 調用Objects.equals(a,b)可避免空指針錯誤 */cal.get(Calendar.MONTH)從零開始返回,也就是說January(一月)返回0,因此int month = cal.get(Calendar.MONTH)+1才是正確月份;同時,cal.get(Calendar.DAY_OF_WEEK)是從周日開始,返回1,周一返回2,因此該值-1才是正確星期,同時還需要判定是否為周日(真難用)處理星期可以使用一個從周日開始的String[ ]數組,直接使用String[ i-1 ]來進行輸出(舒服點了)
jvm有String常量池(注意是 常 量 池,常量。盯久了不認識這倆字了),但是new String對象是在堆中的,new String拼接也是在堆中,不在常量池,字符串還有個inertn()方法,用于獲取常量池引用:s2=s1.intern(),此時s1==s2為true
DateFormat為抽象類,格式化處理日期使用SimpleDateFormat類
Calendar類內部維護了一個fields[]數組,存儲時間信息,get()方法傳入的常量值就是數組下標。如cal.get(Calendar.YEAR)和cal.get(1)是一樣的(CalendarYEAR 值為 1)
基本類型快速轉化字符串可以加空字符串。如Sting s=1+"";
method ( int... arr )可變參數,不用構件數組而是直接傳遞多個參數。如void method(int... arr);method(1,2,3,4);
JVM內存分布
棧(也叫虛擬機棧)、堆,方法區,寄存器(也叫程序計數器),本地方法棧
棧:Java棧中存放的是一個個的棧幀,每個棧幀對應一個被調用的方法。因此遞歸很容易爆棧233333.
堆:存放數組與對象,對象不被引用之后會被垃圾回收。
方法區:保存.class文件,常量池,(還有靜態方法?)
具體可以看這個博客,寫的很清楚。
Comparable和Comparator
Comparable:強行對實現它的每個類的對象進行整體排序。這種排序被稱為類的自然排序,類的compareTo方法被稱為它的自然比較方法。只能在類中實現compareTo()一次,不能經常修改類的代碼實現自己想要的排序。實現此接口的對象列表(和數組)可以通過Collections.sort(和Arrays.sort)進行自動排序,對象可以用作有序映射中的鍵或有序集合中的元素,無需指定比較器。
Comparator強行對某個對象進行整體排序。可以將Comparator 傳遞給sort方法(如Collections.sort或 Arrays.sort),從而允許在排序順序上實現精確控制。還可以使用Comparator來控制某些數據結構(如有序set或有序映射)的順序,或者為那些沒有自然順序的對象collection提供排序。
總結:重寫compareTo(Object ob)方法時,ob為第一個元素,this是后一個元素。因此,this-ob即為升序(與默認相同),如果是引用類型,直接調用compareTo方法(默認升序,想降序在前面加 - 返回反數即可)。compare()方法同理,第一個參數為后面的元素,第二個參數為前面的元素,因此,o1-o2為升序,o2-o1為降序(這兩個函數返回值的意義為:整數:表示大于,0表示等于,負數表示小于)
Collections.sort(list, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {int result = o2.getAge()-o1.getAge();//以學生的年齡降序//可以編寫多個規則:/*if(result==0){//第一個規則相同時 下一個規則 姓名的首字母 升序result = o1.getName().charAt(0)-o2.getName().charAt(0);}*/return result;} }); /*這里,注意,o1是后面的元素,o2是前面的元素返回 1、0 表示不交換,-1表示交換,同理正數和0不交換,負數交換。*/ //lambda Collections.sort(list, (o1, o2) -> {return o2.getAge()-o1.getAge(); });List、Set和數組互轉
list、set轉數組:
List<String> list = new ArrayList<String>(); /*list.toArray()無參方法返回Object數組,用Object[]接收強轉會拋異常;list.toArray(數組):若數組長度小于list長度,轉化失敗,數組內容不變;若長度相等,則正好轉化;若數組長度大于list長度,可以轉化,但是最后一個元素的下一個會被賦null,也就是數組[list.size()]這個位置會被賦null;*/ String[] array=list.toArray(new String[list.size()]);數組轉list、set:
List<String> list = new ArrayList<>(Arrays.asList(array)); Set<String> set = new HashSet<>(Arrays.asList(array)) //或者使用Collections.adAll()方法: List<String> list = new ArrayList<String>(array.length);//list Set<String> set = new HashSet<String>(array.lenth);//set Collections.addAll(list, array); Collections.addAll(set,array);list、set互轉:
Set<String> set = new HashSet<>(list); List<String> list = new ArrayList<>(set); //畢竟都是Collection┓(?′?`?)┏用流裝箱拆箱還不是太明白,以后再看吧。
上面三種方式不能用于基本類型,因此需要對基本類型數組裝箱拆箱,可以使用JDK8的Stream方式Integer[] ints= IntStream.of(arr).boxed().collect(Collectors.toList()).toArray(new Integer[0]);List<Integer> list = Arrays.stream(arr).boxed().collect(Collectors.toList());(這里是錯的,不是所有的基本類型,試了下char和boolean數組不能用,int和double可以,具體什么原因以后再更)
用Stream處理int數組
更新:使用Stream進行拆裝箱
import java.util.Arrays; import java.util.List; import java.util.stream.Collectors;public class Main {public static void main(String[] args) {int[] data = {4, 5, 3, 6, 2, 5, 1};// int[] 轉 List<Integer>List<Integer> list1 = Arrays.stream(data).boxed().collect(Collectors.toList());// Arrays.stream(arr) 可以替換成IntStream.of(arr)。// 1.使用Arrays.stream將int[]轉換成IntStream。// 2.使用IntStream中的boxed()裝箱。將IntStream轉換成Stream<Integer>。// 3.使用Stream的collect(),將Stream<T>轉換成List<T>,因此正是List<Integer>。// int[] 轉 Integer[]Integer[] integers1 = Arrays.stream(data).boxed().toArray(Integer[]::new);// 前兩步同上,此時是Stream<Integer>。// 然后使用Stream的toArray,傳入IntFunction<A[]> generator。// 這樣就可以返回Integer數組。// 不然默認是Object[]。// List<Integer> 轉 Integer[]Integer[] integers2 = list1.toArray(new Integer[0]);// 調用toArray。傳入參數T[] a。這種用法是目前推薦的。// List<String>轉String[]也同理。// List<Integer> 轉 int[]int[] arr1 = list1.stream().mapToInt(Integer::valueOf).toArray();// 想要轉換成int[]類型,就得先轉成IntStream。// 這里就通過mapToInt()把Stream<Integer>調用Integer::valueOf來轉成IntStream// 而IntStream中默認toArray()轉成int[]。// Integer[] 轉 int[]int[] arr2 = Arrays.stream(integers1).mapToInt(Integer::valueOf).toArray();// 思路同上。先將Integer[]轉成Stream<Integer>,再轉成IntStream。// Integer[] 轉 List<Integer>List<Integer> list2 = Arrays.asList(integers1);// 最簡單的方式。String[]轉List<String>也同理。// 同理String[] strings1 = {"a", "b", "c"};// String[] 轉 List<String>List<String> list3 = Arrays.asList(strings1);// List<String> 轉 String[]String[] strings2 = list3.toArray(new String[0]);} }參見此博文
數組打亂
一種方式是轉化list,使用Collections.shuffle(list)進行打亂,另一種方式是:
從數組的最后一個位置(假設下標是n)開始向前掃描,然后隨機生成一個0到n之間的隨機數(這里必須包括n,不然最后一個數一定會變),假設該隨機數是r1,然后將數組最后一個位置(下標n)與r1位置互換,之后開始掃面下一個數(下標為n-1),然后隨機生成一個0到(n-1)之間的隨機數,假設該隨機數是r2,然后將數組倒數第二個位置(下標為n-1)與r2位置互換,然后繼續掃面下一個數(下標為n-2),就這樣一直迭代下去。在這個迭代過程中,可以保證掃面點左邊的數字都是尚未確定位置的,而右邊的數字都是已經安排好位置的。
//若為基本類型則修改掉泛型即可 public static <T> void shuffle(T[] arr) {for (int i = arr.length; i > 0; i--) {int r = new Random().nextInt(i);//取值0到lenth-1T temp = arr[i - 1];arr[i - 1] = arr[r];arr[r] = temp; } }一個簡單的雙色球問題
遇見個挺簡單的題,但是由這個題擴展出許多有意思的東西包括上面的裝箱和數組打亂
做題記錄
同時知道了Arrays.binarySearch()的用法,這里貼兩個鏈接,寫的挺清楚的鏈接1和鏈接2
- IDEA在debug模式下用Alt+F8可以打開Evaluate Expression計算表達式窗口,可以動態獲取某一個值(這是個神器!)
Set
Set判斷元素是否重復通過調用被添加元素的hashCode()方法,因此,對于自定義類,需要重寫hashCode()和equals()方法
調用被添加元素的hashCode(),和HashSet中已有元素的hashCode比較是否相同
如果不相同,直接存儲
如果相同,調用equals方法比較是否相同
不相同,直接存儲元素
相同,認為是同一元素.不存儲
int[] arr; arr = {1, 2};//這種初始化形式只有在聲明的時候才能用(之前沒注意到這點) //這種是對的 int[] arr = {1,2}; //這種也是可以的 int[] arr2; arr2 = new int[]{1,2,3};
實現Runnable接口必須實現無參無返回值的run()方法
主方法中String[] args的意思是Java程序在運行的時候可以傳參,比如
public class Test {public static void main(String[] args) {for (int i = 0; i < args.length; i++) {System.out.println(args[i]);}} }在控制臺執行 javac Test.java編譯
java Test AAA BBB CCC運行
運行結果會是:
AAA
BBB
CCC
即三個參數會在main方法運行前傳入args數組
this在Java中屬于一個隱式變量,記錄著調用當前方法的對象的地址
使用迭代器迭代list時,修改list會拋出ConcurrentModificationException異常
集合不能存儲基本類型,只能存儲引用類型
Scanner的nextLine和nextInt一般不要混用,因為:nextLine遇到回車結束;nextInt遇到回車結束后會留下一個空格。因此混用時需要在nextInt下面再放一個nextLine來讀取留下的那個空格
return可以結束方法,或者System.exit(0)結束虛擬機
- 可以使用\t在控制臺輸出規整的字符
- Pattern和matcher的簡單實用(先貼個博客再說):
- Pattern對象由靜態方法:Pattern.compile(regex)創建,
- Pattern對象有個matcher(string)方法,參數為需要匹配的字符串,該方法返回Matcher對象
- Matcher對象有三個主要方法,matches(),lookingAt(),find()
- matches()返回布爾值,匹配整個字符串,也就是說整個字符串都需要符合正則規則,才會返回true
- lookingAt()返回布爾值,從開頭匹配,也就是說開頭有符合正則的,就會返回true
- find()返回布爾值,只要發現符合正則規則的,就會返回true
- 也就是說,一個快捷的匹配方式為Pattern.compile(regex).matcher(string).find()就可以知道string里是否含有regex的字符串了。
- Matcher有個成員方法group(),可以返回匹配到的字符串,以及start()和end()方法獲得匹配到的字符串的開始和結束的下標。(想要matcher.group()方法,必須先matcher.find()方法,切忌!要不然總是報錯)
- 只有當匹配操作成功,才可以使用start(),end(),group()三個方法,否則會拋出java.lang.IllegalStateException,也就是當matches(),lookingAt(),find()其中任意一個方法返回true時,才可以使用。
properties.load(new FileInputStream(path))load方法執行后其參數流是打開狀態。
轉載于:https://www.cnblogs.com/lixin-link/p/10991694.html
總結
以上是生活随笔為你收集整理的Java基础查漏补缺(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java学习路线详解
- 下一篇: 图像像素灰度内插(Matlab实现)