201621123031 《Java程序設計》第9周學習總結

做業09-集合與泛型


1.本週學習總結

1.1 以你喜歡的方式(思惟導圖或其餘)概括總結集合與泛型相關內容。

  • 1、泛型的基本概念html

    泛型是JDK 1.5的一項新特性,它的本質是參數化類型(Parameterized Type)的應用,也就是說所操做的數據類型被指定爲一個參數,在用到的時候在指定具體的類型。這種參數類型能夠用在類、接口和方法的建立中,分別稱爲泛型類、泛型接口和泛型方法。java

  • 2、關於向上轉型和向下轉型
    爲何會提到這個呢,主要是由於在沒有出現泛型以前,程序員是對Object引用進行「向下轉型」和「向上轉型」操做來實現某些類型的轉換。「向上轉型」是安全的,可是在「向下轉型中」如果用錯了類型就會出現異常。如:
package other;
public class Test {
    private Object a; // 定義Object類型成員變量
    
    public Object getA() { // 設置get方法
        return a;
    }
    
    public void setA(Object a) { // 設置set方法
        this.a = a;
    }
    
    public static void main(String[] args) {
        Test t = new Test();
        t.setA(new Float(12.3));
        Integer f = (Integer)(t.getA());
        System.out.println(f);
    }
}

由於不存在語法錯誤,因此編譯器不會報錯,可是在運行的時候會出現ClassCastException的異常。由此看來,「向下轉型」操做一般會出現問題,而泛型機制能夠很好的解決這個問題。程序員

  • 3、泛型的常規用法
    1.泛型類的定義
    泛型類是具備一個或多個類型變量的類,語法以下:
MutiOverClass<T1,T2>    //MutiOverClass爲泛型類名稱

2.泛型接口的定義
泛型接口和泛型類的定義方法相似,語法以下:算法

interface MutiOverInte<T1,T2>

3.泛型方法的定義
泛型方法的定義就比較複雜,其語法以下:

圖片引用自安全

  • 4、類型通配符ide

    在泛型機制中,提供了類型通配符,其主要做用是在建立一個泛型類對象時限制這個泛型類的類型實現或繼承某個接口或類的子類。要聲明這樣一個對象可使用「?」通配符來表示,同時使用extends關鍵字來對泛型加以限制。函數

其語法以下:工具

泛型類名稱<? extends List> a = null  
//<? extends List>表示類型未知,當須要使用該泛型對象時,能夠單獨實例化

另外,泛型類不止能夠向下限制,還能夠進行向上限制,這就要用到super關鍵字便可,如泛型類名稱<? super List> a = null學習

1.2 選作:收集你認爲有用的代碼片斷

//菱形語法
List<String> strList = new ArrayList<String>(); //java7之前
List<String> strList = new ArrayList<>();   //java7時
//java的foreach語句
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
numbers.stream().filter(i -> i % 2 == 0)..forEach(System.out::println);
//使用Map.Entry對元素進行遍歷,並使用匿名內部類實現對map中元素的排序
List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {

            @Override
            public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
                if (o1.getValue() == o2.getValue()) {
                    return o1.getKey().compareTo(o2.getKey());
                }
                return o2.getValue() - o1.getValue();
            }

        });

2. 書面做業

本次做業題集集合測試

1. List中指定元素的刪除(題集題目)

1.1 實驗總結。並回答:列舉至少2種在List中刪除元素的方法。

答:這題比較容易,就是一開始遍歷List的時候,沒有考慮到從0開始遍歷刪除元素時後面元素下標的變化,致使有些本該刪除的元素沒有被刪除。
在List中刪除元素的方法:

//刪除list中的偶數元素
        List<Integer> list = new ArrayList<Integer>();
        for(int i=0;i<10;i++){      //往list中添加元素
            list.add(i);        
        }
//方法一:從前日後遍歷刪除元素
        for(int i=0;i<list.size();i++){
            if(list.get(i)%2==0){
                list.remove(i);
                i--;
        }
        }
//方法二:反向遍歷刪除元素
        for(int i=list.size()-1;i>=0;i--){
            if(list.get(i)%2==0)
                list.remove(i);
        }
//方法三:利用Iterator刪除元素
        for(Iterator<Integer> iterator = list.iterator();iterator.hasNext(); ){
            int e = iterator.next();
            if(e%2==0)
                iterator.remove();
        }
//方法四:新建一個新集合來刪除元素
        List<Integer> newList = new ArrayList<Integer>();
        for(Integer e:list){
            if(e%2==0)
                newList.add(e);
        }
        list.removeAll(newList);
//方法五:利用removeIf刪除某一個元素
        list.removeIf(e -> e%2==0);
//輸出刪除完成後列表(以上五個運行結果都同樣,就貼一張圖了)
System.out.println(list);

運行結果:

//方法六:利用forEach()過濾元素
        list.stream().filter(e ->e%2==1).forEach(System.out::println);

運行結果:

2. 統計文字中的單詞數量並按出現次數排序(題集題目)

誒,上次的做業中彷佛寫過了,那就照搬過來吧

2.1 僞代碼(不得複製代碼,不然扣分)

建立HashMap對象map
循環讀入文章中的單詞
IF 讀入單詞爲」!!!!!」
退出循環
ELSE
    IF map中沒有相應的key
        添加單詞到map中並設置value爲1
    ELSE 
        將key對應的value值加1

建立ArrayList對象list
實現Collections接口對map對象進行排序
輸出map的長度
輸出排序後list中前十個數據

2.2 實驗總結

答:這題中用到了HashMap,key值爲單詞,value值爲單詞出現的次數,這題比較複雜的地方就是要使用一個可以存放Map數據ArrayList來實現Collections接口來實現相應的排序。
關鍵代碼以下:

List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {

            @Override
            public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
                if (o1.getValue() == o2.getValue()) {
                    return o1.getKey().compareTo(o2.getKey());
                }
                return o2.getValue() - o1.getValue();
            }

        });

其中Map.Entry爲Map的一個內部接口,它表示Map中的一個實體(一個key-value對)。接口中有getKey(),getValue方法。使用它能夠更方便咱們去訪問Map中的元素。

3. 倒排索引(題集題目)

本題較難,作不出來沒關係。但必定要有本身的思考過程,要有提交結果。

3.1 截圖你的代碼運行結果

3.2 僞代碼(不得複製代碼,不然扣分)

建立Map對象map,其中key類型爲String,value類型爲ArrayList
建立ArrayList對象line
循環讀入文章中的單詞
IF 讀入單詞爲"!!!!!"
退出循環
ELSE
    IF map中沒有相應的key
        添加單詞到map中並將當前行數的值添加到value中
    ELSE 
        判斷當前行數是否已經存在於value中,若沒有,則添加當前行數到value中
建立迭代器Iterator
遍歷輸出map中的內容
輸入一行字符串以空格分開
IF map中不一樣時存在指定單詞
    輸出found 0 results
ELSE
    求指定單詞的value值的交集
IF 交集爲0
    輸出found 0 results
ELSE
    輸出交集以及交集中數字對應的行數

3.3 實驗總結

答:這題比較好玩的地方就是要在要將Map的value的類型設置爲ArrayList的,以方便存儲單詞出現行數,而後要注意的點就是將某一單詞的當前行數加入ArrayList中時要判斷列表中是否已經存在該行的行數,即這個單詞是否在這行中出現屢次,以前一直錯誤就是由於沒有考慮到一行能夠存放多個相同單詞,而後使用Iterator迭代器進行Map的輸出。最後求單詞出現函數的實質其實就是求指定單詞的出現行數的交集,能夠用retainAll方法來求。

4.Stream與Lambda

編寫一個Student類,屬性爲:

private Long id; 
private String name; 
private int age; 
private Gender gender;//枚舉類型 
private boolean joinsACM; //是否參加過ACM比賽

建立一集合對象,如List ,內有若干Student對象用於後面的測試。

4.1 使用傳統方法編寫一個搜索方法List<Student> search(Long id, String name, int age, Gender gender, boolean joinsACM),而後調用該方法將id>某個值,name爲某個值, age>某個值, gender爲某個值,參加過ACM比賽的學生篩選出來,放入新的集合。在main中調用,而後輸出結果。(截圖:出現學號、姓名)

測試數據:

List<Student1> student = new ArrayList<Student1>();
        student.add(new Student1(1L,"wang",15,Gender.man,false));
        student.add( new Student1(8L,"zhao",16,Gender.woman,true));
        student.add( new Student1(87L,"chen",17,Gender.man,false));
        student.add ( new Student1(100L,"xu",18,Gender.woman,false));
        student.add( new Student1(67L,"chen",19,Gender.man,true));
        student.add( new Student1(90L,"chen",20,Gender.man,true));
        student.add( new Student1(177L,"chen",21,Gender.man,true));
//搜索方法
    static List<Student1> search(Long id, String name, int age, Gender gender, boolean joinsACM,List<Student1> list){
        List<Student1> student = new ArrayList<Student1>();
        for(Student1 e:list){
            if(e.getId()>id&&e.getName().equals(name)&&e.getGender()==gender&&e.isJoinsACM()==joinsACM){
                student.add(e);
            }
        }
        return student;
        
    }
//main函數
        List<Student1> newStudent = search(50L, "chen",18,Gender.man, true,student);
        for(Student1 e:newStudent){
            System.out.println(e.toString());
            }
        }

運行截圖:

4.2 使用java8中的stream(), filter(), collect()編寫功能同4.1的代碼,並測試(要出現測試數據)。構建測試集合的時候,除了正常的Student對象,再往集合中添加一些null,你編寫的方法應該能處理這些null而不是拋出異常。(截圖:出現學號)

List<Student1> newStudent = student.stream().filter(e -> e!=null&&e.getId()>50&&e.getName().equals("chen")&&e.getAge()>18&&e.getGender()==Gender.man&&e.isJoinsACM()==true).collect(Collectors.toList());

測試數據(只是添加了兩個null進去):

student.add(new Student1(1L,"wang",15,Gender.man,false));
        student.add( new Student1(8L,"zhao",16,Gender.woman,true));
        student.add(null);
        student.add( new Student1(87L,"chen",17,Gender.man,false));
        student.add(null);
        student.add ( new Student1(100L,"xu",18,Gender.woman,false));
        student.add( new Student1(67L,"chen",19,Gender.man,true));
        student.add( new Student1(90L,"chen",20,Gender.man,true));
        student.add( new Student1(177L,"chen",21,Gender.man,true));

運行結果:

其實和上面的結果是同樣的……

5. 泛型類:GeneralStack

題集jmu-Java-05-集合之GeneralStack

5.1 GeneralStack接口的代碼

interface GeneralStack<T>{
    T push(T item);            
    T pop();                 
    T peek();               
    public boolean empty();
    public int size();     
}

5.2 結合本題與之前做業中的ArrayListIntegerStack相比,說明泛型有什麼好處

答:在ArrayListIntegerStack中,棧中的元素只能是Integer類型的,內容比較有侷限性,而使用了泛型,則能夠根據本身的要求來規定入棧元素的類型,就像這題中,咱們只要定義一個接口就能夠實現對IntegerDoubleCar類型的棧操做,減小了代碼的冗餘,使用起來也很靈活。

6. 選作:泛型方法

基礎參考文件GenericMain,在此文件上進行修改。

6.1 編寫方法max,該方法能夠返回List中全部元素的最大值。List中的元素必須實現Comparable接口。編寫的max方法需使得String max = max(strList)能夠運行成功,其中strList爲List<String>類型。也能使得Integer maxInt = max(intList);運行成功,其中intList爲List<Integer>類型。注意:不得直接調用Collections.max函數。

//max方法
    public static <T extends Comparable<T>> T max(List<T> list){
        Collections.sort(list);
        return list.get(list.size()-1); 
    }

測試數據:

List<String> listA = new ArrayList<String>();
        listA.add("aaaaa");
        listA.add("bbbbb");
        listA.add("ddddd");
        listA.add("ccccc");
        System.out.println(max(listA));

運行結果:

測試數據:

List<Integer> listB = new ArrayList<Integer>();
        listB.add(11111);
        listB.add(22222);
        listB.add(44444);
        listB.add(33333);
        System.out.println(max(listB));

運行結果:

6.2 選作:現有User類,其子類爲StuUser,且均實現了Comparable接口。編寫方法max1,基本功能同6.1,使得User user = max1(stuList);能夠運行成功,其中stuList爲List 類型。也可以使得Object user = max(stuList)運行成功。

//max1方法
    public static <T extends Comparable< ? super T>> T max1(List<T> list,Comparator< ? super T> comp) {
        
        Collections.sort(list,comp);
        return list.get(list.size()-1);
      }

測試數據:

List<StuUser> listC = new ArrayList<StuUser>();
        listC.add(new StuUser(11, "aaa"));
        listC.add(new StuUser(22, "bbb"));
        listC.add(new StuUser(44, "ccc"));
        listC.add(new StuUser(33, "eee"));
        listC.add(new StuUser(33, "ddd"));
        User user1 = max1(listC,new StuUserComparator());
        Object user2 = max1(listC,new StuUserComparator());
        System.out.println(user1);
        System.out.println(user2);

運行結果:

6.3 選作:編寫int myCompare(T o1, T o2, Comparator c)方法,該方法能夠比較兩個User對象,也能夠比較兩個StuUser對象,傳入的比較器c既能夠是Comparator<User>,也能夠是Comparator<StuUser>。注意:該方法聲明未寫全,請自行補全。

//myCompare方法
    public static <T> int myCompare(T o1,T o2, Comparator<? super T> c){
        return c.compare(o1, o2);
}

測試數據:

User user1 = new User(123);
        User user2 = new User(321);
        int a = myCompare(user1,user2,new UserReverseComparator());
        if(a<0)
            System.out.println(user1+" > "+user2);
        else if(a==0)
            System.out.println(user1+" = "+user2);
        else
            System.out.println(user1+" < "+user2);
StuUser stu1 = new StuUser(44, "ccc");
        StuUser stu2 = new StuUser(55, "ddd");
        int b = myCompare(stu1,stu2,new StuUserComparator());
        if(a<0)
            System.out.println(stu1+" > "+stu2);
        else if(a==0)
            System.out.println(stu1+" = "+stu2);
        else
            System.out.println(stu1+" < "+stu2);

運行結果:

7. 選作:逆向最大匹配分詞算法

集合實驗文件中的第07次實驗(集合).doc文件,裏面的題目6.

7.1 寫出僞代碼(不得直接複製代碼)

建立HashSet對象dic
Add word to dic
設置最大截取長度maxLength
While has nextLine{
    Creat list
    While line 的長度不爲0{
        從後往前以最大截取長度截取句子e
        If dic.continue(e){
            Add e to list
            line = 截取字符串(0,line.size-e.size)
            從後往前以最大截取長度截取句子e

 
        }
        Else
            去掉e的第一個字符繼續操做
    }
倒序輸出list中的元素
 }

7.2 截圖你的代碼運行結果。

3.碼雲及PTA

題目集:jmu-Java-05-集合

3.1. 碼雲代碼提交記錄

  • 在碼雲的項目中,依次選擇「統計-Commits歷史-設置時間段」, 而後搜索並截圖

    3.2 截圖PTA題集完成狀況圖

    須要有兩張圖(1. 排名圖。2.PTA提交列表圖)


    3.3 統計本週完成的代碼量

    須要將每週的代碼統計狀況融合到一張表中。
    本身的目標能實現嗎?
    恩第一週定的目標是到期末可以寫7000+行的代碼,看樣子應該能夠完成??

周次 總代碼量 新增代碼量 總文件數 新增文件數
2 607 607 15 15
3 1642 1035 33 18
5 2044 402 42 9
6 2874 830 57 15
7 3161 287 63 6
8 4299 1138 72 9
9 4831 532 81 9
10 5475 644 93 12

4. 評估本身對Java的理解程度

嘗試從如下幾個維度評估本身對Java的理解程度

維度 程度
語法 pta的題目基本上沒問題吧,一些比較偏的語法也能夠經過百度解決
面向對象設計能力 這方面的能力還比較弱,在設計購物車系統的時候充分暴露了出來,正在努力改善中
應用能力 也許藉助一些資料能夠完成一些簡單的工具?
至今爲止代碼行數 5475
相關文章
相關標籤/搜索