java內部類、接口、集合框架、泛型、工具類、實現類


 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

StringBuffer:安全
StringBuild:不安全
ArrayList:線程不安全
Vector:線程安全

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;
        
    }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM