Java_4 泛型和集合

目錄:

  • 泛型
  • Collection
  • List
  • Map
  • Set
  • Collections
  • 常用的排序 & 搜索算法


泛型

即參數化數據類型,將數據類型變成可變的參數。
1.只能是類類型;
2.泛型參數可以有多個;
3.可以用 extends語句<T extends superClass>表示類型上界,T只能是superClass或子類 或 super語句<K super childClass>表示類型下界,K是childClass的父類;
4.可以是通配符類型Class<?>.

  • 泛型類
// TestDemo.java
class Test<T>{
    private T ob;

    public Test(T ob){
        this.ob = ob;
    }
    public T getOb(){
        return ob;
    }
    public void setOb(T ob){
        this.ob = ob;
    }
    public void showType(){
        System.out.println("T 的類型:" + ob.getClass().getName());
    }
}

public class TestDemo{
    public static void main(String[] args){
        Test<Integer> intOb = new Test<Integer>(88);
        intOb.showType();
        int i = intOb.getOb();
        System.out.println("value = " + i);
        System.out.println("*********************");
        Test<String> strOb = new Test<String>("hello world!");
        strOb.showType();
        String st = strOb.getOb();
        System.out.println("value= " + st);
    }
}
  • 泛型方法
// Animal.java
public class Animal{
    public Animal(){
        System.out.println("動物");
    }
}

// Dog.java
public class Dog extends Animal{
    public Dog(){
        System.out.println("狗");
    }
}

// Test.java
public class Test{
    public <T, S extends T> T testDemo(T t, S s){
        System.out.println("T 類型是:" + t.getClass().getName());
        System.out.println("S 類型是:" + s.getClass().getName());
        return t;
    }

    public static void main(String[] args){
        Test t = new Test();
        Animal a = new Animal();
        Dog d = new Dog();
        Animal an = t.testDemo(a, d);
        System.out.println("an 類型是:" + an.getClass().getName());
    }
}

Collection

集合框架是爲表示和操作集合而規定的一種統一的標準結構。
集合框架包括三個部分:
1.對外的接口;
2.接口的實現;
3.對集合運算的算法。
Collection是java集合框架的一個根接口,是List、Set、Queue的父接口,其定義了對集合的“增刪改查”的方法。

List

一個接口,不能直接實例化,需要一個具體的類來輔助實例化。
內容有序,可重複。
List接口實現的類有:ArrayList(實現動態數組)、Vector(實現動態數組)、LinkedList(實現鏈表)、Stack(實現堆棧).

// Student.java
public class Student{
    public String id;
    public String name;
    public Student(String id, String name){
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString(){
        return "Student{" +
            "id='" + id + "'" +
            "name='" + name + "'}";
    }
}

// ListTest.java
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Comparator;
import java.util.Arrays;

public class ListTest{

    public List<Student> stds;

    public ListTest(){
        this.stds = new ArrayList<Student>();
    }

    public void testAdd(){
        Student st1 = new Student("1", "張三");
        stds.add(st1);
        Student temp1 = stds.get(0);
        System.out.println("添加了學生:" + temp1.id + ":" + temp1.name);

        Student st2 = new Student("2", "李四");
        stds.add(0, st2);

        Student[] st3 = {new Student("3", "王二"),
            new Student("4", "趙五"), new Student("5", "陳七"),
            new Student("6", "周無")};
        stds.addAll(Arrays.asList(st3));

        Student[] st4 = {new Student("7", "鄭四"), new Student("8", "錢三")};
        stds.addAll(3, Arrays.asList(st4));
    }

    public void testGet(){
        System.out.println("for 訪問:");
        int size = stds.size();
        for (int i = 0; i < size; i++){
            Student st = stds.get(i);
            System.out.println("學生:" +st.id + ":" + st.name);
        }
    }

    public void testIterator(){
        System.out.println("迭代器:");
        Iterator<Student> it = stds.iterator();
        while (it.hasNext()){
            Student st = it.next();
            System.out.println("學生:" + st.id + ":" + st.name);
        }
    }

    public void testForEach(){
        System.out.println("for each 訪問:");
        for (Student st:stds){
            System.out.println("學生:" + st.id + ":" + st.name);
        }
    }

    public void testStream(){
        System.out.println("java8 Stream 訪問:");
        stds.stream()
            .sorted(Comparator.comparing(x -> x.id))
            .forEach(System.out::println);
    }

    public void testModify(){
        System.out.println("修改:");
        stds.set(4, new Student("3", "吳酒"));
        testForEach();
    }

    public void testRemove(){
        System.out.println("刪除:");
        Student st = stds.get(4);
        System.out.println("學生:" + st.id + ":" + st.name);
        stds.remove(st);
        testForEach();
    }

    public static void main(String[] args){
        ListTest lt = new ListTest();
        lt.testAdd();
        lt.testGet();
        lt.testForEach();
        lt.testIterator();
        lt.testStream();
        lt.testModify();
        lt.testRemove();
    }
}

Map

Map接口用於存儲鍵值對,鍵值對是成對出現的,其中的鍵不能重複,每個鍵最多映射一個值。
Map中的鍵/值以Entry類型的對象形式存在。
HashMap是基於Map接口的一個類,其中的Entry對象是無序的,key和value均可爲null,但key只能有一個爲null。

// Course.java
public class Course{
    public String id;
    public String name;
    public Course(String id, String name){
        this.id = id;
        this.name = name;
    }
}

// MapTest.java
import java.util.Map;
import java.util.Map.Entry;
import java.util.HashMap;
import java.util.Scanner;
import java.util.Set;

public class MapTest{

    public Map<String, Course> courses;

    public MapTest(){
        this.courses = new HashMap<String, Course>();
    }

    public void testPut(){
        Scanner console = new Scanner(System.in);

        for (int i = 0; i < 3; i++){
            System.out.println("輸入 id:");
            String ID = console.next();
            Course cr = courses.get(ID);
            if (cr == null){
                System.out.println("輸入課程:");
                String name = console.next();
                Course newCourse = new Course(ID, name);
                courses.put(ID, newCourse);
                System.out.println("添加課程:" + courses.get(ID).name);
            } else {
                System.out.println("課程 ID 被佔用");
                continue;
            }
        }
    }

    public void testKeySet(){
        System.out.println("鍵************:");
        Set<String> keySet = courses.keySet();
        for (String crID:keySet){
            Course cr = courses.get(crID);
            if (cr != null){
                System.out.println("課程:" + cr.name);
            }
        }
    }

    public void testRemove(){
        Scanner console = new Scanner(System.in);
        while (true){
            System.out.println("刪除 ID:");
            String ID = console.next();
            Course cr = courses.get(ID);
            if (cr == null){
                System.out.println("ID 不存在");
                continue;
            } else {
                courses.remove(ID);
                System.out.println("刪除課程:" + cr.name);
                break;
            }
        }
    }

    public void testEntrySet(){
        System.out.println("遍歷Map:");
        Set<Entry<String, Course>> entrySet = courses.entrySet();
        for (Entry<String, Course> entry:entrySet){
            System.out.println("鍵:" + entry.getKey());
            System.out.println("值:" + entry.getValue().name);
        }
    }

    public void testModify(){
        System.out.println("輸入修改 ID:");
        Scanner console = new Scanner(System.in);
        while (true){
            String crID = console.next();
            Course cs = courses.get(crID);
            if (cs == null){
                System.out.println("ID 不存在,重輸入");
                continue;
            } else {
                System.out.println("當前 ID 課程爲:" + cs.name);
                System.out.println("新課程名稱爲:");
                String name = console.next();
                Course newCourse = new Course(crID, name);
                courses.put(crID, newCourse);
                System.out.println("修改成功");
                break;
            }
        }
    }

    public static void main(String[] args){
        MapTest mt = new MapTest();
        mt.testPut();
        mt.testKeySet();
        mt.testRemove();
        mt.testModify();
        mt.testEntrySet();
    }
}

Set

稱集,其中元素無序且不重複。
HashSet由哈希表支持,不保證set的迭代順序。

// PD.java
import java.util.Set;
import java.util.HashSet;

public class PD{

    public String id;
    public String name;
    public Set<Student> stds;
    public PD(String id, String name){
        this.id = id;
        this.name = name;
        this.stds = new HashSet<Student>();
    }
}

// Student.java
public class Student{
    public String id;
    public String name;
    public Student(String id, String name){
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString(){
        return "Student{" +
            "id='" + id + "'" +
            "name='" + name + "'}";
    }
}

// SetTest.java
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Scanner;

public class SetTest{

    public List<Student> stds;

    public SetTest(){
        stds = new ArrayList<Student>();
    }

    public void testAdd(){
        Student st1 = new Student("1", "張三");
        stds.add(st1);

        Student[] st2 = {new Student("2", "李四"), new Student("3", "王五"),
            new Student("4", "趙六"), new Student("5", "錢七")};
        stds.addAll(Arrays.asList(st2));
    }

    public void testForEach(){
        System.out.println("for each: ");
        for (Student st:stds){
            System.out.println("學生:" + st.id + ":" + st.name);
        }
    }

    public void testForEachForSer(PD pd){
        for (Student s: pd.stds){
            System.out.println("選擇學生:" + s.id + ":" + s.name);
        }
    }

    public static void main(String[] args){
        SetTest st = new SetTest();
        st.testAdd();
        st.testForEach();
        PD pd = new PD("1", "張老");
        System.out.println("請:" + pd.name + "選擇組成員");
        Scanner console = new Scanner(System.in);
        for (int i = 0; i < 3; i++){
            System.out.println("輸學號:");
            String ID = console.next();
            for (Student s:st.stds){
                if (s.id.equals(ID)){
                    pd.stds.add(s);
                }
            }
        }
        st.testForEachForSer(pd);
        console.close();
    }
}

Collections

java.util.Collections是一個工具包,包含了許多對集合操作的靜態方法。

// CollectionsDemo.java
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;

public class CollectionsDemo{

    public static void main(String[] args){
        List<Integer> list = new ArrayList<Integer>();
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(7);
        list.add(9);
        list.add(12);
        System.out.print("初始順序:");
        list.forEach(v -> System.out.print(v + "\t"));

        Collections.shuffle(list);
        System.out.print("\n打亂順序:");
        list.forEach(v -> System.out.print(v + "\t"));

        Collections.reverse(list);
        System.out.print("\n反轉集合:");
        list.forEach(v -> System.out.print(v + "\t"));

        Collections.swap(list, 0, list.size() - 1);
        System.out.print("\n交換第1和最後一位:");
        list.forEach(v -> System.out.print(v + "\t"));

        Collections.sort(list);
        System.out.print("\n自然升序: ");
        list.forEach(v -> System.out.print(v + "\t"));

        System.out.print("\n二分查找7的位置:" +
            Collections.binarySearch(list, 7));

        System.out.print("\n返回線程安全的list: ");
        List<Integer> synchronizedList = Collections.synchronizedList(list);
    }
}

常用的排序 & 搜索算法

  • 排序算法
    • 插入排序
      在這裏插入圖片描述
// InsertSort.java
import java.util.Arrays;

public class InsertSort{
    public static void sort(int[] arr){
        int temp;
        for (int i = 1; i < arr.length; i++){
            for (int j = 0; j < i; j++){
                if (arr[i] < arr[j]){
                    temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }

    public static void main(String[] args){
        int[] ints = {5, 3, 4, 1, 2};
        sort(ints);
        System.out.println(Arrays.toString(ints));
    }
}
- 冒泡排序

在這裏插入圖片描述

import java.util.Arrays;

public class BubbleSort{
    public static void sort(int[] arr){
        int temp;
        for (int i = 0; i < arr.length - 1; i++){
            for (int j = 0; j < arr.length - i - 1; j++){
                if (arr[j] > arr[j + 1]){
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

    public static void main(String[] args){
        int[] ints = {5, 3, 4, 1, 2};
        sort(ints);
        System.out.println(Arrays.toString(ints));
    }
}
- 歸併排序

在這裏插入圖片描述

import java.util.Arrays;

public class MergeSort{

    public static void mergeSort(int[] arrays, int left, int right){
        if (left < right){
            int middle = (left + right) / 2;
            mergeSort(arrays, left, middle);
            mergeSort(arrays, middle + 1, right);
            merge(arrays, left, middle, right);
        }
    }

    public static void merge(int[] arr, int left, int middle, int right){
        int[] temp = new int[right - left + 1];
        int i = left;
        int j = middle + 1;
        int k = 0;
        while (i <= middle && j <= right){
            if (arr[i] < arr[j]){
                temp[k++] = arr[i++];
            } else {
                temp[k++] = arr[j++];;
            }
        }
        while (i <= middle){
            temp[k++] = arr[i++];
        }
        while (j <= right){
            temp[k++] = arr[j++];
        }
        for (int l = 0; l < temp.length; l++){
            arr[l + left] = temp[l];
        }
    }

    public static void main(String[] args){
        int[] ints = {5, 3, 4, 1, 2, 9, 8, 7, 6};
        mergeSort(ints, 0, ints.length - 1);
        System.out.println(Arrays.toString(ints));
    }
}
- 快速排序

先選擇一個基準,然後以此爲基準,將小的放了前面,將大的值放到後面,最後基準值處於中間;然後遞歸的,分別從小於的部分和大於的部分中找到基準重複上一步,直到排序完成。
在這裏插入圖片描述

import java.util.Arrays;

public class QuickSort{

    public static void sort(int[] arr, int head, int tail){
        if (head >= tail || arr == null || arr.length <= 1){
            return;
        }
        int i = head, j = tail, pivot = arr[(head + tail) / 2];
        while (i <= j){
            while (arr[i] < pivot){
                ++i;
            }
            while (arr[j] > pivot){
                --j;
            }
            if (i < j){
                int t = arr[i];
                arr[i] = arr[j];
                arr[j] = t;
                ++i;
                --j;
            } else if (i == j){
                ++i;
            }
        }
        sort(arr, head, j);
        sort(arr, i, tail);
    }

    public static void main(String[] args){
        int[] ints = {5, 3, 4, 1, 2, 6, 7, 9, 8};
        sort(ints, 0, ints.length - 1);
        System.out.println(Arrays.toString(ints));
    }
}
  • 搜索算法
    1.線性搜索
    按一定順序查找,直到找到值爲止。
public class LinearSearch{

    public static void main(String[] args){
        int[] ints = {5, 3, 4, 1, 2};
        System.out.println(search(ints, 4));
    }

    public static int search(int[] arr, int key){
        for (int i = 0; i < arr.length; i++){
            if (arr[i] == key){
                return i;
            }
        }
        // 找到不
        return -1;
    }
}

2.二分查找
又叫二分搜索、折半搜索、對數搜索。
在有序數組中查找特定元素。

public class BinarySearch{

    public static void main(String[] args){
        int[] ints = {1, 2, 3, 4, 5, 6, 7, 8};
        System.out.println(search(ints, 4));
    }

    public static int search(int[] arr, int key){
        int low = 0;
        int high = arr.length - 1;
        while (low <= high){
            int middle = (high + low) / 2;
            if (key == arr[middle]){
                return middle;
            } else if (key < arr[middle]){
                high = middle - 1;
            } else {
                low = middle + 1;
            }
        }
        // 找不到
        return -1;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章