1.成員內部類。
(1)成員內部類的實例化:
外部類名.內部類名 變量名=外部類對象.new 內部類名();
class Person{ class Test{ } } Person p=new Person(); Person.Test t=p.new Test();
(2)在內部類中訪問外部類屬性或方法。
外部類名.this.屬性名
Person.this.name
(3)成員內部類聲明的注意事項
①內部類不能與外部類重名。
②成員內部類中不能出現靜態屬性,靜態方法和靜態內部類。
但是靜態常量例外。
private static final String name="1";//此情況可以使用
class Test{//成員內部類 private String name; private int age; public void say(){ System.out.println(Person.this.name);//訪問外部類的 System.out.println("Person中的Test的say方法"); } }
2.靜態內部類。
(1)使用static修飾的內部類,叫做靜態內部類。
(2)實例化:外部類名.內部名 變量=new 外部類名.內部類名();
class Person{ public String name="1"; public Static int age="12"; static class Test{ } } Person.Test t=new Person.Test();
注意與成員內部類實例化的區別。
(3)靜態內部類中不能訪問外部類的非靜態屬性和方法。
但可以訪問外部類中的靜態屬性和方法,使用外部類名.屬性名;
Person.age;
(4)外部類不能訪問靜態內部類的非靜態屬性和方法,但可以訪問靜態內部類的的靜態屬性和方法,外部類名.屬性名。
Test.age;
(5)【靜態內部類和成員內部類的區別】
1.聲明方式和實例化方式不同。成員內部類不帶static
靜態內部類實例化: Person.Test t=new Person.Test();
成員內部類實例化: Person.Test t=p.new Test();
2.成員內部類中不能出現靜態屬性和方法,但靜態內部類可以。
3.外部類和內部類的互相訪問權限不同:
①靜態內部類中不能訪問外部類的非靜態屬性和方法。
但可以訪問外部類中的靜態屬性和方法,使用外部類名.屬性名;
②成員內部類中不能出現靜態屬性,靜態方法和靜態內部類。
但是靜態常量例外。
static class Test1{ public static String test="111"; public void say(){ System.out.println("Test1"); } }
3.【局部內部類】(一般不用)。
(1)定義在某個類中的方法中的內部類,稱為局部內部類。
(2)局部內部類是對外部完全隱藏的,只能在其作用域范圍內被實例化。
(3)局部內部類可以訪問外部類的屬性和方法,使用外部類.this.屬性名;
Person.this.name;
(4)局部內部類:不能訪問其所在方法中的變量,只能訪問常量。
(5)注意:局部內部類不能使用訪問修飾符修飾,因為它不屬於類的成員,它屬於方法中的局部變量。
public void eat(){ // final String name1="123"; class Test2{ public String name="123"; public void test(){ System.out.println(Person.this.name); // System.out.println(name1); } } Test2 t=new Test2(); System.out.println(t.name); } }
4.匿名內部類。
new Test1(){
};
(1)寫法
(2)含義:相當於一個匿名類繼承了Test1類,使用匿名內部類將直接返回當前子類的對象。
Test1 t=new Test1(){};
(3)相當於:①一個匿名內部類,繼承了Test1類。
②匿名內部類返回一個子類對象,並付給父類引用。
因此這一行代碼用於向上轉型。
(4)匿名內部類通常用於直接實例化抽象類或接口。
Test1 t=new Test1(){
//重寫抽象類Test1中的所有的抽象方法
//相當於一個匿名內部類,繼承了Test1類,然后返回這個匿名內部類的對象。
};
Test1 t2=new Test1(){ public int age=12; public void eat(){ System.out.println(age); System.out.println("eat"); } public void say(){ System.out.println("匿名重寫Test1類的say方法"); } }; //向上轉型,會丟失掉子類特有的屬性和方法,new Test1(){}.eat(); t2.say();
5.使用內部類模擬多繼承 。
class A{ public void a() { System.out.println("a"); } } class B{ public void b(){ System.out.println("b"); } } class C{ class A1 extends A{ } class B1 extends B{ } public void a(){ new A1().a();//不管A類是不是抽象類都可以,如果是A則要考慮是不是抽象類 } public void b(){ new B1().b(); } }
C c=new C(); //結果a,b c.a(); c.b();
1.【接口的定義】
(1)接口名/接口文件與類類似,接口也是使用.java文件編寫。
(2)聲明接口的關鍵字:interface,接口名命名規范與類名相同,習慣上,接口可以用I開頭表示。
(3)接口的訪問修飾符只能使用public和default修飾,不能使用protected和private(與外部類相同)。
(4)接口中的所有的屬性,只能是公共的,靜態的,常量。
public static final int NAME=1;
而且,public/static/final都可以省略,省略后依然是公共的,靜態的常量。
int NAME=1;
(5)接口中所有的方法必須是公共的抽象方法。
而且,接口中的抽象方法,也可以省略public/abstract關鍵字。
(public abstract) void say();
2.【實現類實現接口】
(1)一個類實現接口使用implements關鍵字
(2)實現類實現一個接口,必須重寫接口中的所有抽象方法,除非這個類是抽象類。
一個類可以使用多個接口,多個接口之間,使用逗號隔開。
class Desk implements IUsb2,3()
一個類如果實現多個接口,必須重寫所有接口中的所有方法。
(3)接口的引用可指向其實現類的對象(類似於父類引用指向子類對象)
IUsb2 usb=new UDesk();
因此可以使用接口實現多態。
3.【接口繼承接口】
(1)接口可以繼承接口,使用extends關鍵字,接口繼承與類的接口一樣。
interface IUsb3 extends IUsb2{}
(2)接口可以多繼承,多個父接口用逗號分隔,子接口繼承多個父接口,將擁有所有父接口的抽象方法。
interface IUsb3 extends IUsb2,IUsb1{}
(接口不能被實例化)
4.【接口和抽象類的區別】
它們的本質區別:
抽象類是一個類,接口是一個接口,子類繼承抽象類,要求子類必須和父類是同一類事物,必須符合is-a關系。
接口只是對功能的擴展。
多個實現類實現接口時,並不要求所有的實現類是一類事物。
接口符合like-a關系,理解為XXX具備一個XXX功能。比如人類狗類都具有吃飯功能,都具有吃飯接口,但是人類狗類的吃飯功能不能從同一個父類中繼承。
(1)抽象類只能單繼承,接口可以多繼承,多實現。
(2)抽象類可以有自己的屬性,接口中只能有靜態常量。
(3)抽象類可以有非抽象方法,接口中的所有方法都必須是抽象方法(接口中的抽象方法可以省略abstract )。
(4)抽象類是一個類,接口是一種規范。
子類繼承抽象類,要求子類必須和父類是同一類事物。
接口並不要求多個實現類是同一類事物,只能進行設計與實現的分離。
interface IUsb2 { /* public final static*/ int NAME=1; // public String name="1";//name是靜態的,斜體的,接口的靜態屬性 /*public abstract*/public void useUsb2();//在類中沒有大括號必須加abstract修飾 } interface IUsb3 extends IUsb2{ void useUsb3(); } class UDesk implements IUsb2,IUsb3{ @Override public void useUsb2() { // TODO Auto-generated method stub System.out.println("U盤使用useUsb2接口讀取數據"); } public void useUsb3() { // TODO Auto-generated method stub System.out.println("U盤使用useUsb3接口讀取數據"); } } class PC{ private IUsb2 usb2 ; public PC(IUsb2 usb2){ super(); this.usb2=usb2; } public void useUsb(){ usb2.useUsb2(); } } public class Usb{ public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(IUsb2.NAME); IUsb2 usb=new UDesk(); PC pc=new PC(new UDesk() ); pc.useUsb(); } }
1.【java的集合框架】
接口:
collection map
list set
實現類:
ArrayList HashSet HashMap
LinkList LinkHashSet LinkHashMap
Vector TreeSet TreeMap
HashTable

2.【四個接口的區別】
(1)Collection:存儲不唯一,無序的數據。
(2)List:存儲有序的,不唯一的數據。
(3)Set:存儲無序的,唯一的數據。
(4)Map:以鍵值對的形式存儲數據,以鍵取值,鍵不能重復,值能重復。
3.【List 接口】
(1)常用方法:
①add()在列表的最后添加元素
②add(index.obj)在列表的指定位置插入元素
③size();返回當前列表的元素個數
④get(int index);返回下標為index的元素
如果沒有泛型約束,返回Object類型,需要強轉,如果有泛型約束,返回約束類型,無需強轉。
⑤clear();清除列表中的所有數據
isEmpty();檢測列表是否為空
⑥contains()方法,傳入一個對象,檢測列表中是否包含該對象。
如果傳入的是String和基本數據類型,可以直接對比。
如果傳入的是實體類對象,則默認只比對兩個對象的地址,因此,需要在實體類重寫equals()方法。
⑦indexof()傳入一個對象,返回在該對象在列表中首次出現的地址。
lastindexof()返回最后一次的地址。
⑧傳入一個下標,或者一個對象,刪除指定元素
如果傳入下標,返回被刪除的元素對象,如果下標大於size(),顯示越界異常。
如果傳入對象,則要求重寫equals方法,返回true或false顯示刪除是否成功。
⑨set(index,obj)用新傳入的對象,將指定位置的元素替換掉,返回被替換掉的元素對象。
sublist()截取一個子列表返回list類型
toArray()將列表轉成數組,返回一個Object[]類型
(2)ArrayList(例如新聞列表)
是實現了長度可變的數組,在內存空間中開辟一串連續的空間,長度可以隨時修改,這種存儲結構再循環
遍歷和隨機訪問元素的速度比較快。
(3)LinkedList
使用鏈表結構存儲數據,再插入和刪除元素師速度比較快。
LinkedList的特有方法:
.addfirst();開頭插入元素
.addlast();結尾插入元素
removefirst()刪除第一個元素
removelast()刪除最后一個元素。返回被刪除的元素
peekfirst();檢索但不刪除第一個元素
peeklast();檢索但不刪除最后一個元素
pullfirst()檢索刪除第一個元素
getfirst()檢索但不刪除第一個元素
getlast()檢索但不刪除最后一個元素
//ArrayList是實現類,實現List接口。 ArrayList list=new ArrayList(); list.add("list1"); list.add("list2"); list.add("list3"); list.add("list4"); list.add(2,"list0"); System.out.println(list.contains("list1"));//返回true System.out.println(list); //返回數組類型的 /** * 使用for循環遍歷列表 */ for(int i=0;i<list.size();i++){ if(list.get(i) instanceof String){ String s=(String)list.get(i);//向下轉型,強轉 Integer強轉會出現轉換異常。 System.out.println(s); }else{ Integer s=(Integer) list.get(i); System.out.println(s); } }//返回字符串的形式
1.【set接口】
(1)常用方法:與list接口基本相同。
但是由於Set接口中的元素是無序的,因此沒有用下標方法。
例如get(index),remove(index)add(index,obj)
(2)Set的特點:無序,唯一
(3)HashSet,底層是調用HashMap的相關方法,傳入數據后,根據數據的hashcode進行散列運算,得到一個散列值后在進行運算,
確定元素在序列中存儲的位置。
HashSet如何確定兩個對象是否相等:
①先判斷對象的HashCode(),如果HashCode不同,肯定不是一個對象。
如果HashCode相同,繼續判斷equals方法
②重寫equals()方法。
所以使用HashSet存儲實體對象時,必須重寫對象的HashCode()和equals()兩個方法;
(4)LinkedHashSet,在HashSet的基礎上,新增了一個鏈表,
用鏈表來記錄HashSet元素存放的順序,因此使用迭代器遍歷時,可以按照放入的順序一次獨處。
(5)TreeSet將存入的元素進行排序,然后再進行輸出,如果存入的是實體對象,那么實體類必須實現comparable接口,並重寫compareTo方法。
或者也可以在實例化TreeSet的同時,通過構造函數傳入一個比較器(一個實現了comparator接口並重寫了compare的方法的對象)
//使用匿名內部類拿到一個比較器對象
Set<Person> set=new TreeSet<Person>(new Comparator(){ public int compare(Person p1,Person p2){ return p1.getId()-p2.getId(); } });
//自定義一個比較類,實現Comparator接口。
Set<Person> set=new TreeSet<Person>(new Compare()); class Compare implements Comparator(){ //重寫compare方法 }
(5)[comparable 接口和comparator的區別]
①Comparable由實體類實現,重寫ComparaTo()方法
實體類實現Comparable接口以后,TreeSet使用空參構造即可。
②Comparator需要單獨一個單獨比較類進行實踐,重寫compare方法。
實例化TreeSet的時候,需要傳入一個比較類的對象。
2.【Map】
(1)Map接口特點:以鍵值對的形式存儲數據,以鍵取值鍵不能重復,值不能重復。
(2)Map接口的常用方法:
.clear()
replace(key,value)①put(key,value);向map的最后追加一個鍵值對
map1.put("001", "小紅");
②get(key);通過建,收到值
System.out.println(map1.get("001"));
③.clear();清除Map中的所有數據
④containsValue(obj)檢測是否包含指定的值
containsKey(obj)檢測是否包含指定的鍵,如果傳入對象,需要重寫equals方法。
(3)【HashTable和HashMap的區別】
①HashTable是線程安全的(線程同步),HashMap是線程不安全的(線程不同步)
②HashTable的鍵不能為null,HashMap的鍵可以為null
③HashMap的初始容量為16,Hashtable初始容量為11,兩者的填充因子默認都是0.75。
④HashMap擴容時是當前容量翻倍即:capacity*2,Hashtable擴容時是容量翻倍+1即:capacity*2+1。
⑤HashMap繼承了AbstractMap,HashTable繼承Dictionary抽象類,兩者均實現Map接口。
⑥在HashMap 中不能用get()方法來判斷HashMap 中是否存在某個鍵,而應該用containsKey(),方法來判斷。Hashtable 的鍵值都不能 為null,所以可以用get()方法來判斷是否含有某個鍵。
(4)【LinkedHashMap】(無序)
可以使用鏈表,記錄數據放入的次序,進入讓讀出的順序和放入的順序一致,與LinkedHashSet一致
Map<String,String> map1=new LinkedHashMap<String,String>();
(5)【TreeMap】
根據鍵的順序,進行排序后,輸出。如果傳入的是實體對象,必須重寫比較函數,詳見TreeSet
Map<String,String> map1=new TreeMap<String,String>();
Map<String,String> map1=new Hashtable<String,String>(); map1.put("001", "小紅"); map1.put("002", "小王"); map1.put("003", "小綠"); map1.put("004", "小黃"); map1.put(null, "小和"); map1.replace("001", "小哈");//更改 System.out.println(map1); System.out.println("****************"); System.out.println(map1.get("001")); System.out.println("****************"); System.out.println(map1.containsKey("001")); System.out.println(map1.containsValue("小綠"));//
Map<String,String> map1=new HashMap<String,String>(); map1.put("001", "小紅"); map1.put("002", "小王"); map1.put("003", "小綠"); map1.put("004", "小黃"); map1.put(null, "小和"); map1.replace("001", "小哈");//更改 System.out.println(map1); System.out.println("****************"); System.out.println(map1.get("001")); System.out.println("****************"); System.out.println(map1.containsKey("001")); System.out.println(map1.containsValue("小綠"));//
(6)遍歷Map的方式
①遍歷Map的方式1:KeySet
System.out.println("****************"); Set<String> keys=map1.keySet(); Iterator<String> it=keys.iterator(); while(it.hasNext()){ String key=it.next(); System.out.println(key+"*******"+map1.get(key)); }
② 遍歷Map的方式2:values
System.out.println("****************"); Collection<String> values=map1.values(); Iterator<String>it1=values.iterator(); while(it1.hasNext()){ System.out.println(it1.next());//可以以鍵取值,不能以值取鍵 }
③遍歷Map的方式3:entrySet
System.out.println("****************"); Set<Map.Entry<String,String>> set2=map1.entrySet(); /*foreach*/ for(Map.Entry<String, String> entry:set2){ System.out.println(entry.getKey()+"****"+entry.getValue()); }
/*Entry*/ System.out.println("****************"); Iterator<Map.Entry<String, String>> it3=set2.iterator(); while(it3.hasNext()){ Map.Entry<String, String>entry =it3.next(); //entry 是Java給我們提供的一種特殊的數據類型其實是一個數據對。 //鍵就是這條記錄的鍵,使用getkey()去到 //值就是這條記錄的值,使用getValue()取到 System.out.println(entry.getKey()+"****"+entry.getValue()); }
Collections是Java中專門用於操作集合的工具類。
Collection是一個接口。
1.向集合中添加多個數據
(1)傳入數據
ArrayList<String> list = new ArrayList<String>(); list.add("test04"); list.add("test09"); list.add("test03"); list.add("test02"); list.add("test01"); list.add("test07");
Collections.addAll(list, "01","02","test01");
System.out.println(list);
(2)傳入對象
List<PersonDemo> list1 = new ArrayList<PersonDemo>(); list1.add(new PersonDemo(1,"zhangsan")); list1.add(new PersonDemo(5,"lisi")); list1.add(new PersonDemo(2,"wanger")); list1.add(new PersonDemo(6,"zhaowu")); list1.add(new PersonDemo(3,"liergou")); Collections.addAll(list1, new PersonDemo(10,"zhngsan"),new PersonDemo(8,"wangr")); System.out.println(list1);
2.將集合中的所有元素,全部替換為指定元素。把list里的內容替換成呵呵噠。
Collections.fill(list, "呵呵噠!");
System.out.println(list);
3.排序。
(1)sort方法: 對集合中的數據進行排序。
Collections.sort(list1);
System.out.println(list1);
(2)如果集合存儲的是一個實體對象,那么:
① 實體類實現comparable接口,並重寫CompareTo方法;
② 在sort的第二個參數,傳入比較器。 比較器需實現comparator接口,並重寫compare方法。
Collections.sort(list1, new Comparator<PersonDemo>() { @Override public int compare(PersonDemo o1, PersonDemo o2) { // TODO Auto-generated method stub return o1.getId() - o2.getId(); } }); System.out.println(list1);
4.使用binarySearch,那么集合必須先排序。
同樣,如果比較的是實體對象,依然需要通過兩種方式實現比較器。
①
Collections.sort(list1);
System.out.println(Collections.binarySearch(list1, new PersonDemo(6,"zhaowu")));
②匿名內部類比較器
System.out.println(Collections.binarySearch(list1, new PersonDemo(6,"zhaowu"), //匿名內部類 new Comparator<PersonDemo>() { @Override public int compare(PersonDemo o1, PersonDemo o2) { // TODO Auto-generated method stub return o1.getId() - o2.getId(); } } ));
(4)拿到集合中最大、最小的值。
System.out.println(Collections.max(list1));
System.out.println(Collections.min(list1));
5..replaceAll(): 將列表的指定值,用新值替換。
如果是實體對象,需要在實體類中重寫 equals()方法。
System.out.println(Collections.replaceAll(list1, new PersonDemo(1,"zhangsan"), new PersonDemo(1,"zhangsansan")));//后面返回前面,返回boolean類型 System.out.println(list1);//返回替換后的列表
6.反轉列表中的所有元素。(前后交換)
Collections.reverse(list1);
System.out.println(list1);
7.對集合的元素,進行隨機排序。
Collections.shuffle(list1);
System.out.println(list1);
8.將集合中指定的元素位置,進行交換。(把第三個和第0個交換)
Collections.swap(list1, 0, 3);
System.out.println(list1);
1、 [泛型]
(1) 泛型就是“參數化類型”。
在定義類型時,不將類型定死,而是采用泛型參數的形式進行定義。調用時傳入具體的泛型參數。
2、[泛型類的特點]
在聲明類的時候,進行泛型約束,這樣的類,稱為泛型類。
class Test<T>{ // <T> 可以理解為泛型聲明是的形參。可以用任何字母代替。 常用T N E // 在泛型類中,T就可以當做特殊的數據類型進行使用 private T arg; } // 泛型調用時,需要將實際的數據類型進行傳入。 Test<String> test1 = new Test<String>("姜浩真帥!"); Test<Integer> test2 = new Test<Integer>(123);
(1) 泛型只在編譯階段生效。 同一個類通過不同泛型拿到的對象,使用getClass()判斷是屬於同一個類的。
System.out.println(test1.getClass() == test2.getClass()); // 取到的test1的類為 Test類,而不是Test<String>
(2)同一個類,通過不同泛型拿到的對象,相互不兼容。 不能互相賦值。
test2 = test1; // test1與test2不兼容。
即便,聲明的泛型數據類型有父子類關系,那么用這兩個數據類型聲明的泛型類,還是不兼容。
Test<Integer> test2 = new Test<Integer>(123); Test<Number> test3 = new Test<Number>(123); test3 = test2; // 依然不兼容。
(3) 泛型類,在實例化的時候,可以不傳入泛型。 類中的數據類型,以賦值時傳入的變量類型為主。
Test test3 = new Test(); // 實例化泛型類,沒有傳入泛型實參 test3.setArg("123"); // 類中的泛型變為String test3.setArg(456); // 類中的泛型被修改為Integer
(4) 實例化泛型時,只能傳入類名,可以是系統類也可以是自定義的實體類,但不能傳入基本數據類型。
Test<int> test1 = new Test<int>(); // ×
(5)泛型約束時,可以同時約束多個泛型:
class Test1<T1,T2>{ public T1 arg1; public T2 arg2; } Test1<String,Integer> test4 = new Test1<String,Integer>();
(6)不能對確切的泛型類型使用instanceof操作。如下面的操作是非法的,編譯時會出錯。
test2 instanceof Test2<Integer>; // × test2 instanceof Test2; // √
3.[泛型通配符與上下邊界]
(1) 為了解決,同一個類的多個不同泛型對象,相互不兼容的問題。 可以使用泛型通配符:?
Test<?> test2 = new Test<String>(); // ? 表示可以兼容所有類的數據類型。
(2) 泛型通配符上邊界: 使用? extends 類名,表示通配符只支持指定類及指定類的子類。
Test<? extends Number> test5 = new Test<Number>(); // √ Test<? extends Number> test5 = new Test<Integer>(); // √ Test<? extends Number> test5 = new Test<String>(); // ×
(3) 泛型通配符下邊界: 使用 ? super 類名,表示通配符只支持指定類及其超類。
Test<? super Integer> test6 = new Test<Integer>(); // √ Test<? super Integer> test6 = new Test<Number>(); // √ Test<? super Integer> test6 = new Test<String>(); // ×
4. [泛型接口]
(1) 聲明泛型接口:
interface inter<T>{ void Test(T t); }
(2)實現類,如果實現泛型接口,那么不能直接使用接口的泛型,需要重新聲明:
class Test3<T> implements inter<T>{ @Override public void Test(T t) {} }
(3)如果實現類,不想作為泛型類。 那么,可以在實現接口時,直接給接口的泛型賦值:
class Test3 implements inter<String>{ @Override public void Test(String t) {} }
5. [泛型方法]
(1) 泛型方法可以獨立於泛型類,在任何類中都可以單獨使用:
class Test{ public static <T> void test(T t){ } } //調用: Test.test("String"); Test.test(int);
(2) 使用泛型方法,可以實現可變參數的方法:
class Test{ // 使用T... 表示可以接受N個 任意類型的參數; 也可以接受數組 public static <T> void test(T... t){ } }
調用: Test.test("String","String2",123,true);
Test.test(new int[]{123,456,789});
(3)只有在方法中聲明了<T>的方法,才叫泛型方法。
而如果在方法中,使用了類的泛型,這不能稱為泛型方法。
class Test<T>{ // 這個不是泛型方法 public void test(T t){} }
注意: 靜態方法不能使用類泛型。 只能將靜態方法,單獨聲明為泛型方法。
Math類
Math類位於java.lang包,不需要導包。
1.返回圓周率。
System.out.println(Math.PI);
2.返回絕對值。
System.out.println(Math.abs(-10));//絕對值,返回10
3.立方根。
System.out.println(Math.cbrt(27));//返回3
4.平方根。
System.out.println(Math.sqrt(9));//返回3
5.最大最小值。
System.out.println(Math.max(20, 19));
System.out.println(Math.min(20, 19));
6.求a的b次方冪。
System.out.println(Math.pow(a, b));
7.floor返回一個小於指定浮點數的第一個整數,返回的是double類型,10.0。
System.out.println(Math.floor(10.5));//10.0 System.out.println(Math.floor(-10.5));//-11.0
8.ceil返回一個大於指定浮點數的第一個整數,返回的是double類型,11.0。
System.out.println(Math.ceil(10.5));//11.0 System.out.println(Math.ceil(-10.5));//-10.0
9.進行四舍五入,返回一個整數類型,若果傳入double返回long,如果float返回int。
System.out.println(Math.round(10.5f));//11 System.out.println(Math.round(10.3d));//10
10.保留三位小數。
public static double rounds(double num,int count){ return Math.round(num*Math.pow(10, count))/Math.pow(10, count); } System.out.println(rounds(10.354546,3));//diao用
System.out.println(Math.round(10.354546*Math.pow(10, 3))/Math.pow(10, 3));//10.355
11.返回最接近參數的一個整數,如果是10.5與10和11同時接近,那么返回偶數10。
System.out.println(Math.rint(10.5));//10
12.返回【0,6)的int(左閉右開)隨機一個。
System.out.println((int)(Math.random()*6));// 強轉成int返回【1,6)的
13.返回ASCII碼值。
System.out.println(Arrays.toString("abcdef".getBytes()));//返回數組97 98 99 100 101 102 103
14.判斷是否有.java返回boolean。
System.out.println("abc.java".endsWith(".java"));
15.把0替換成o,把I替換成i。
String s="43434344250000000ooooooooooIIIIIIIIIi"; System.out.println(s.replace("0", "o"));//4343434425oooooooooooooooooIIIIIIIIIi System.out.println(s.replace("I", "1"));//43434344250000000oooooooooo111111111i
Date類
1.date空參構造: 取到當前時間。
Date date = new Date(); System.out.println(date);
2.setTime(): 傳入一個長整型,重新設置date時間。
Date date = new Date();
date.setTime(1000*60*60*24);//計算機元年
System.out.println(date);
3.傳入一個long類型的時間戳,取到指定時間。
date.getTime(): 取到一個時間的時間戳: 從0時區,1970年1月1日0:0:0 到當前時間的毫秒數。
Date date = new Date(); date.setTime(1000*60*60*24); System.out.println(date.getTime());
4.compareTo(): 前面>參數 返回 1 前面<參數 返回 -1 前面=參數 返回 0
equals(): 比對兩個時間是否相等。
before(): 檢測一個時間是不是在指定時間之前
after(): 檢測一個時間是不是在指定時間之后
System.out.println("3******************");
System.out.println(date.before(date2));
System.out.println(date.after(date2));
System.out.println(date.compareTo(date2));
System.out.println(date.equals(date2));
5.求出從95年到現在的年數。
Date date = new Date(); System.out.println(date);//當前時間 Date date3 = new Date(95, 11, 23); System.out.println((date.getTime() - date3.getTime())/1000/60/60/24/365);//求出從95年到現在的年數
6.日期。
.
7.format(): 用於傳入一個Date類型的參數,並返回格式化之后的字符串。
parse(): 將字符串格式的時間,轉成Date類型。 要求傳入的字符串格式,必須與實例化時的模式,保持完全一致
toPattern(): 返回當前格式化的模式字符串。
SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss E"); String dateFormat = sf.format(new Date());
Date date3 = null; try {//捕獲異常 date3 = sf.parse("2018年04月13日 14:09:47 星期五"); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(dateFormat); System.out.println(date3); System.out.println(sf.toPattern());
Calendar 日歷類
1. Calendar日歷類是一個抽象類,不能直接通過new拿到對象,必須使用 Calendar.getInstance();拿到。
Calendar calendar = Calendar.getInstance();
System.out.println(calendar);
2.在原來的基礎上減了兩天。
calendar.add(Calendar.DAY_OF_MONTH, -2);
System.out.println(calendar);
3.getTime 返回一個日期對象。
Date date4 = calendar.getTime();
System.out.println(sf.format(date4));
4.根據calendar提供的常量,獲得指定字段。
System.out.println(calendar.get(calendar.MONTH));
System.out.println(calendar.get(calendar.DAY_OF_WEEK));
5.計算當前為星期幾。
String[] arr = {"星期天","星期一","星期二","星期三","星期四","星期五","星期六"}; int week = calendar.get(calendar.DAY_OF_WEEK)-1; System.out.println(arr[week]);
Random類
Random()類:取隨機數
兩種構造:
①空參構造
②傳入一個種子數
③傳入一個種子數,只要種子數相同,那么在相同次數(Random)取到的隨機數肯定相同,這是偽隨機數。
1.隨機輸出一個整數。
Random ran=new Random();//隨機輸出正負均可 System.out.println(ran.nextInt());
2.nextInt()隨機獲得一個整數
nextInt(n)隨機獲得從0到n的隨機數
nextDouble();
Random ran1=new Random(10); System.out.println(ran1.nextInt(10));//10以內隨機 System.out.println(ran1.nextInt(10));//10以內隨機 System.out.println(ran1.nextInt(10));//10以內隨機 System.out.println(ran1.nextInt(10));//10以內隨機
3.返回毫秒數。
Date date=new Date(); System.out.println(date.getTime()/1000/60/60/24); System.out.println(System.currentTimeMillis());
4.隨機返回[95,103)。
Random ran=new Random(); System.out.println(ran.nextInt(8)+95);
Enum枚舉類
枚舉類是一種特殊的類,里面的值全部都是靜態常量。
每個枚舉值都相當於一個本類對象,只不過(對象的值就是對象的名)調用對象的toString方法打印的是對象名。
enum Color{ /** * 每一個枚舉值都是一個本類對象。 * 、所以聲明一個枚舉值,相當於執行下列代碼 * public static final BLUE=new Color(); * public static final PINK=new Color(); * public static final YELLOW=new Color(); */ /** * 在枚舉類中,枚舉值必須要放在第一行,其他所有代碼只能放在枚舉值的后面。 * * 枚舉類中的構造函數,只能是私有化的,在聲明枚舉值時,自動調用。 */ BULE,RED,YELLOW,GREEN,PINK;//本類對象 private Color(){//構造函數在常見對象使用 System.out.println("hahahahahah");//輸出5次,枚舉值的個數。 } }
System.out.println(Color.BULE);
1.toString方法自動調用。
System.out.println(Color.BULE.toString());
調用對象的toString方法打印的是對象名。
返回BULE。
2.取到枚舉類中所有枚舉值。
Color [] colors=Color.values(); for(Color color:colors){ System.out.println(color.toString()); }
3.聲明一個Person枚舉類型的類。
enum Person{ Person1 ("張",12),Person2 ("li",22),Person3 ("chen",22),Person4 ("liu",13),Person0; private String name; private int age; private Person(String name,int age){ this.name=name; this.age=age; } private Person(){ this.name="默認"; this.age=0; } public String toString(){ return name+"------"+age; } }
System.out.println(Person.Person0); System.out.println(Person.Person1);//寫toString方法
單例模式
單例模式:確保某一個類只能產生一個實例。
1.設計思路:
①將構造函數私有化,確保類外部不能使用new關鍵字自己創建對象。
②在類內部實例化一個對象,並通過靜態方法返回。
private static Singleton sing =new Singleton(); //如果這局部是靜態的,public static Singleton getInstance()方法不能調用 private Singleton(){//1 System.out.println("單例模式"); }
2. 惡漢式單例模式,在類加載的時候,就創建了一個對象。
缺點:在類加載的時候就實例化對象,提前占用系統資源
優點:線程安全。
private static Singleton sing =new Singleton(); public static Singleton getInstance(){ return sing; }
3.懶漢式單例模式。
優點:解決了惡漢式單例,一加載就提前占用資源的問題。
缺點:線程不安全。
private static Singleton sing =null; public static Singleton getInstance(){ if(sing==null){ sing =new Singleton(); } return sing; }
4.synchronized同步鎖。
使用synchronized同步鎖,對方法進行加鎖,確保懶漢式單利可以線程安全。
將一個方法或者是代碼塊進行加鎖,同一時間只允許一個線程訪問。
缺點:每次都需要鎖住方法,每一個方法或代碼塊 ,效率低下。
private static Singleton sing =null; public static synchronized Singleton getInstance(){//線程鎖synchronized if(sing==null){ sing =new Singleton(); } return sing; }
5.雙重加鎖的懶漢模式。
只有第一個Sing為null時,才進行線程鎖,
當后續sing不為null時,就無需線程鎖,可以允許多個線程同時拿走sing。
private static Singleton sing =null; public static synchronized Singleton getInstance(){//鎖住哪個類的對象 if(sing==null){ synchronized (Singleton.class) { if(sing==null){ sing =new Singleton(); } } } return sing; }
6.靜態內部類實現單例:
優點:解決了惡漢式提前占用資源的問題,解決了懶漢式線程不安全的問題。
private static class Singleton1{//不能是public外面可以直接實例化,每次都調用,不能實現單例 private static Singleton sing =new Singleton(); } public static Singleton getInstance(){ return Singleton1.sing; }