1. 程式人生 > 其它 >Java高階程式設計精華筆記

Java高階程式設計精華筆記

學習路線

本文是Java高階程式設計精華筆記,是對菜鳥教程中Java面向物件和Java高階程式設計的重要章節進行了學習,整理形成的學習筆記,知識圖譜如下圖所示:

如果想對Java深入學習,可以參考阿里巴巴的技術圖譜

https://developer.aliyun.com/graph/java

繼承

Java使用extends關鍵字來宣告繼承:

class 父類 {
}

class 子類 extends 父類 {
}

示例,子類企鵝和子類老鼠繼承父類動物:

//父類:動物
public class Animal {
    private String name;
    private int id;

    public Animal(String myName, int myid) {
        name = myName;
        id = myid;
    }

    public void eat() {
        System.out.println(name + "正在吃");
    }

    public void sleep() {
        System.out.println(name + "正在睡");
    }

    public void introduction() {
        System.out.println("大家好!我是" + id + "號" + name + ".");
    }
}
//子類:企鵝
public class Penguin extends Animal { 
    public Penguin(String myName, int myid) { 
        super(myName, myid); 
    } 
}
//子類:老鼠
public class Mouse extends Animal { 
    public Mouse(String myName, int myid) { 
        super(myName, myid); 
    } 
}

Java只支援單繼承,不支援多繼承,但可以多重繼承:

  • 子類會繼承父類的非private屬性、方法。

  • 子類可以擴充套件自己的屬性、方法。

  • 子類可以覆蓋父類的方法,用自己的方式實現。

也就是,你的是我的,我的還是我的,我還可以改變你的

  • 構造器,子類不會繼承父類,而且如果父類的構造器有引數,子類必須通過super關鍵字顯式呼叫。

也就是,你老子始終是你老子

implements關鍵字

前面說到了Java使用extends宣告繼承類,而implements用來宣告實現介面,並且可以同時實現多個介面。

public interface A {
    public void eat();
    public void sleep();
}

public interface B {
    public void show();
}

public class C implements A,B {
}

super和this關鍵字

super:用來實現對父類成員的訪問。

this:指向自己的引用。

示例:

class Animal {
  void eat() {
    System.out.println("animal : eat");
  }
}

class Dog extends Animal {
  void eat() {
    System.out.println("dog : eat");
  }
  void eatTest() {
    this.eat();   // this 呼叫自己的方法
    super.eat();  // super 呼叫父類方法
  }
}

public class Test {
  public static void main(String[] args) {
    Animal a = new Animal();
    a.eat();
    Dog d = new Dog();
    d.eatTest();
  }
}

final關鍵字

如果修飾類,則表示類不能被繼承。如果修飾方法,則表示方法不能被子類重寫。

重寫與過載

重寫與過載的區別可以通過下面這張圖來看:

重寫就是子類覆蓋父類,方法名和引數都一樣:

過載就是在一個類裡面的多個方法,方法名相同,引數不同。呼叫時根據入參匹配到不同的方法:

多型

多型是同一個行為具有多個不同表現形式或形態的能力。重寫可以看做是父類和子類之間多型性的一種表現(過載可以理解成多型的具體表現形式),如圖所示:

class Shape {
    void draw() {}
}

class Circle extends Shape {
    void draw() {
        System.out.println("Circle.draw()");
    }
}

class Square extends Shape {
    void draw() {
        System.out.println("Square.draw()");
    }
}

class Triangle extends Shape {
    void draw() {
        System.out.println("Triangle.draw()");
    }
}

多型存在有三個必要條件:

  • 繼承

  • 重寫

  • 父類引用指向子類物件:Parent p = new Child();

當使用多型方式呼叫方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤;如果有,再去呼叫子類的同名方法。

多型有三種實現方式:

  1. 重寫

  2. 介面

  3. 抽象類和抽象方法

抽象類

抽象類更普通類的區別在於,它不能例項化物件,只能被繼承使用。抽象類使用abstract關鍵字定義:

public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   public Employee(String name, String address, int number)
   {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public double computePay()
   {
     System.out.println("Inside Employee computePay");
     return 0.0;
   }
   public void mailCheck()
   {
      System.out.println("Mailing a check to " + this.name
       + " " + this.address);
   }
   public String toString()
   {
      return name + " " + address + " " + number;
   }
   public String getName()
   {
      return name;
   }
   public String getAddress()
   {
      return address;
   }
   public void setAddress(String newAddress)
   {
      address = newAddress;
   }
   public int getNumber()
   {
     return number;
   }
}

抽象方法

抽象類裡面既可以定義普通方法,也可以定義抽象方法:

public abstract class Employee
{
   private String name;
   private String address;
   private int number;

   public abstract double computePay();
}

抽象方法也是通過abstract關鍵字定義,只有方法名,沒有方法體(方法名後面是分號而不是花括號),具體實現由它的子類確定。

抽象方法最終必須被重寫了才能在例項化物件中使用。如果一個類繼承了帶有抽象方法的抽象類,那麼這個類要麼也是抽象類,要麼就必須重寫抽象方法。

介面

介面不是類,它們屬於不同的概念。介面通過interface關鍵字來定義:

public interface Animal {
   public void eat();
   public void travel();
}
  • 介面和介面中的方法是隱式抽象的,不必使用abstract關鍵字。

  • 介面中的方法都是public

類使用implements關鍵字實現介面:

public class MammalInt implements Animal{

   public void eat(){
      System.out.println("Mammal eats");
   }

   public void travel(){
      System.out.println("Mammal travels");
   } 

   public int noOfLegs(){
      return 0;
   }

   public static void main(String args[]){
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
}

類必須實現接口裡面的所有方法,否則會編譯失敗。只有抽象類才可以不實現介面的方法。

一個介面能繼承另一個介面,介面的繼承也是使用extends關鍵字:

// 檔名: Sports.java
public interface Sports
{
   public void setHomeTeam(String name);
   public void setVisitingTeam(String name);
}

// 檔名: Football.java
public interface Football extends Sports
{
   public void homeTeamScored(int points);
   public void visitingTeamScored(int points);
   public void endOfQuarter(int quarter);
}

// 檔名: Hockey.java
public interface Hockey extends Sports
{
   public void homeGoalScored();
   public void visitingGoalScored();
   public void endOfPeriod(int period);
   public void overtimePeriod(int ot);
}

並且介面支援多繼承:

public interface Hockey extends Sports, Event

實現了子介面的類,需要同時實現所有父介面中的方法。

接口裡面也可以沒有方法:

package java.util;
public interface EventListener
{} 

它的主要目的是:

  1. 建立一個公共的父介面。

  2. 讓實現它的類屬於一個特定的型別。

列舉

列舉是一種特殊的類,一般用來表示一組常量。列舉使用enum關鍵字來定義,常量使用逗號,分隔:

enum Color
{
    RED, GREEN, BLUE;
}
 
public class Test
{
    // 執行輸出結果
    public static void main(String[] args)
    {
        Color c1 = Color.RED;
        System.out.println(c1);
    }
}

列舉也可以宣告在內部類中:

public class Test
{
    enum Color
    {
        RED, GREEN, BLUE;
    }
 
    // 執行輸出結果
    public static void main(String[] args)
    {
        Color c1 = Color.RED;
        System.out.println(c1);
    }
}

列舉可以使用for語句遍歷:

enum Color
{
    RED, GREEN, BLUE;
}
public class MyClass {
  public static void main(String[] args) {
    for (Color myVar : Color.values()) {
      System.out.println(myVar);
    }
  }
}

也可以用在switch語句中:

enum Color
{
    RED, GREEN, BLUE;
}
public class MyClass {
  public static void main(String[] args) {
    Color myVar = Color.BLUE;

    switch(myVar) {
      case RED:
        System.out.println("紅色");
        break;
      case GREEN:
         System.out.println("綠色");
        break;
      case BLUE:
        System.out.println("藍色");
        break;
    }
  }
}

enum定義的列舉預設繼承了java.lang.Enum類,具有3個方法:

  • values(),返回列舉中所有常量。

  • ordinal(),返回常量的索引。

  • valueOf(),返回指定字串值的常量。

enum Color
{
    RED, GREEN, BLUE;
}
 
public class Test
{
    public static void main(String[] args)
    {
        // 呼叫 values()
        Color[] arr = Color.values();
 
        // 迭代列舉
        for (Color col : arr)
        {
            // 檢視索引
            System.out.println(col + " at index " + col.ordinal());
        }
 
        // 使用 valueOf() 返回列舉常量,不存在的會報錯 IllegalArgumentException
        System.out.println(Color.valueOf("RED"));
    }
}

列舉跟普通類一樣可以定義變數、方法和建構函式:

enum Color
{
    RED, GREEN, BLUE;
 
    // 建構函式
    private Color()
    {
        System.out.println("Constructor called for : " + this.toString());
    }
 
    public void colorInfo()
    {
        System.out.println("Universal Color");
    }
}
 
public class Test
{    
    // 輸出
    public static void main(String[] args)
    {
        Color c1 = Color.RED;
        System.out.println(c1);
        c1.colorInfo();
    }
}

輸出:

Constructor called for : RED
Constructor called for : GREEN
Constructor called for : BLUE
RED
Universal Color

包可以理解為類的目錄,使用package關鍵字定義:

package com.runoob;
public class Runoob {
      
}

一個公司一般使用它網際網路域名的倒序形式來作為它的包名,比如runoob.com,所有的包名都以com.runoob開頭。

同一個包中的類可以直接訪問,而訪問不同的包需要先import。

//匯入包下所有類
import payroll.*;
//匯入包下某個類
import payroll.Employee;

集合

集合(Collections)和陣列(Arrays)的區別:

  • 長度區別:陣列固定;集合可變。
  • 內容區別:陣列既可以是基本型別,也可以是引用型別;集合只能是引用型別。
  • 儲存型別:陣列只能儲存一種型別;集合可以儲存不同型別(但一般也只儲存一種型別)

集合中只能使用基本型別的包裝類:

集合主要包括兩種型別的容器:Collection和Map,Collection是元素集合,Map是鍵值對。

集合有3個層次:

介面代表集合的抽象資料型別,我們重點關注實現類和演算法,尤其是4種常用實現類:ArrayList、LinkedList、HashSet、HashMap。

ArrayList

ArrayList相當於可以動態修改的陣列。它繼承了AbstractList,並實現了List介面:

定義

import java.util.ArrayList; // 引入 ArrayList 類

ArrayList<E> objectName = new ArrayList<>();  // 初始化

新增元素

使用add()方法:

import java.util.ArrayList;

public class RunoobTest {
    public static void main(String[] args) {
        ArrayList<String> sites = new ArrayList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        System.out.println(sites);
    }
}

訪問元素

使用get()方法:

import java.util.ArrayList;

public class RunoobTest {
    public static void main(String[] args) {
        ArrayList<String> sites = new ArrayList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        System.out.println(sites.get(1));  // 訪問第二個元素
    }
}

修改元素

使用set()方法:

import java.util.ArrayList;

public class RunoobTest {
    public static void main(String[] args) {
        ArrayList<String> sites = new ArrayList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        sites.set(2, "Wiki"); // 第一個引數為索引位置,第二個為要修改的值
        System.out.println(sites);
    }
}

刪除元素

使用remove()方法:

import java.util.ArrayList;

public class RunoobTest {
    public static void main(String[] args) {
        ArrayList<String> sites = new ArrayList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        sites.remove(3); // 刪除第四個元素
        System.out.println(sites);
    }
}

計算大小

使用size()方法:

import java.util.ArrayList;

public class RunoobTest {
    public static void main(String[] args) {
        ArrayList<String> sites = new ArrayList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        System.out.println(sites.size());
    }
}

迭代遍歷

for迴圈:

import java.util.ArrayList;

public class RunoobTest {
    public static void main(String[] args) {
        ArrayList<String> sites = new ArrayList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        for (int i = 0; i < sites.size(); i++) {
            System.out.println(sites.get(i));
        }
    }
}

for-each語句:

import java.util.ArrayList;

public class RunoobTest {
    public static void main(String[] args) {
        ArrayList<String> sites = new ArrayList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        for (String i : sites) {
            System.out.println(i);
        }
    }
}

排序

使用Collections.sort()方法:

import java.util.ArrayList;
import java.util.Collections;  // 引入 Collections 類

public class RunoobTest {
    public static void main(String[] args) {
        ArrayList<String> sites = new ArrayList<String>();
        sites.add("Taobao");
        sites.add("Wiki");
        sites.add("Runoob");
        sites.add("Weibo");
        sites.add("Google");
        Collections.sort(sites);  // 字母排序
        for (String i : sites) {
            System.out.println(i);
        }
    }
}

LinkedList

LinkedList是連結串列,分為單向連結串列和雙向連結串列。

單向連結串列包含2個值,①當前節點的值,②下一個節點的連結:

雙向連結串列包含3個值,①當前節點的值,②向前的節點連結,③向後的節點連結:

與ArrayList相比,LinkedList的增加和刪除的效率更高,而修改和查詢的效率更低。

快速記憶法:

增刪:LinkedList

改查:ArrayList

LinkedList繼承了AbstractSequentialList,實現了很多介面:

定義

// 引入 LinkedList 類
import java.util.LinkedList; 

LinkedList<E> list = new LinkedList<E>();   // 普通建立方法
或者
LinkedList<E> list = new LinkedList(Collection<? extends E> c); // 使用集合建立連結串列

新增元素

import java.util.LinkedList;

public class RunoobTest {
    public static void main(String[] args) {
        LinkedList<String> sites = new LinkedList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        System.out.println(sites);
    }
}

在列表開頭新增元素

使用addFirst()方法:

// 引入 LinkedList 類
import java.util.LinkedList;

public class RunoobTest {
    public static void main(String[] args) {
        LinkedList<String> sites = new LinkedList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        // 使用 addFirst() 在頭部新增元素
        sites.addFirst("Wiki");
        System.out.println(sites);
    }
}

在列表結尾新增元素

使用addLast()方法:

// 引入 LinkedList 類
import java.util.LinkedList;

public class RunoobTest {
    public static void main(String[] args) {
        LinkedList<String> sites = new LinkedList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        // 使用 addLast() 在尾部新增元素
        sites.addLast("Wiki");
        System.out.println(sites);
    }
}

在列表開頭移除元素

使用removeFirst()方法:

// 引入 LinkedList 類
import java.util.LinkedList;

public class RunoobTest {
    public static void main(String[] args) {
        LinkedList<String> sites = new LinkedList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        // 使用 removeFirst() 移除頭部元素
        sites.removeFirst();
        System.out.println(sites);
    }
}

在列表結果移除元素

使用removeLast()方法:

// 引入 LinkedList 類
import java.util.LinkedList;

public class RunoobTest {
    public static void main(String[] args) {
        LinkedList<String> sites = new LinkedList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        // 使用 removeLast() 移除尾部元素
        sites.removeLast();
        System.out.println(sites);
    }
}

獲取列表開頭的元素

使用getFirst()方法:

// 引入 LinkedList 類
import java.util.LinkedList;

public class RunoobTest {
    public static void main(String[] args) {
        LinkedList<String> sites = new LinkedList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        // 使用 getFirst() 獲取頭部元素
        System.out.println(sites.getFirst());
    }
}

獲取列表結尾的元素

使用getLast()方法:

// 引入 LinkedList 類
import java.util.LinkedList;

public class RunoobTest {
    public static void main(String[] args) {
        LinkedList<String> sites = new LinkedList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        // 使用 getLast() 獲取尾部元素
        System.out.println(sites.getLast());
    }
}

迭代元素

可以使用for迴圈:

// 引入 LinkedList 類
import java.util.LinkedList;

public class RunoobTest {
    public static void main(String[] args) {
        LinkedList<String> sites = new LinkedList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        for (int size = sites.size(), i = 0; i < size; i++) {
            System.out.println(sites.get(i));
        }
    }
}

也可以使用for-each語句:

// 引入 LinkedList 類
import java.util.LinkedList;

public class RunoobTest {
    public static void main(String[] args) {
        LinkedList<String> sites = new LinkedList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        for (String i : sites) {
            System.out.println(i);
        }
    }
}

HashMap

HashMap叫做雜湊表,相當於鍵值對(key-value)的字典。它繼承於AbstractMap,實現了Map、Cloneable、java.io.Serializable介面:

定義

import java.util.HashMap; // 引入 HashMap 類

HashMap<Integer, String> Sites = new HashMap<>();

HashMap中只能使用基本型別的包裝類,因為HashMap也是集合一種,在集合中只能使用包裝類。

新增元素

使用put()方法:

// 引入 HashMap 類      
import java.util.HashMap;

public class RunoobTest {
    public static void main(String[] args) {
        // 建立 HashMap 物件 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 新增鍵值對
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        System.out.println(Sites);
    }
}

訪問元素

使用get()方法:

// 引入 HashMap 類      
import java.util.HashMap;

public class RunoobTest {
    public static void main(String[] args) {
        // 建立 HashMap 物件 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 新增鍵值對
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        System.out.println(Sites.get(3));
    }
}

刪除元素

使用remove()方法:

// 引入 HashMap 類      
import java.util.HashMap;

public class RunoobTest {
    public static void main(String[] args) {
        // 建立 HashMap 物件 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 新增鍵值對
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        Sites.remove(4);
        System.out.println(Sites);
    }
}

刪除所有鍵值對

使用clear()方法:

// 引入 HashMap 類      
import java.util.HashMap;

public class RunoobTest {
    public static void main(String[] args) {
        // 建立 HashMap 物件 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 新增鍵值對
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        Sites.clear();
        System.out.println(Sites);
    }
}

計算大小

使用size()方法:

// 引入 HashMap 類      
import java.util.HashMap;

public class RunoobTest {
    public static void main(String[] args) {
        // 建立 HashMap 物件 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 新增鍵值對
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        System.out.println(Sites.size());
    }
}

迭代

推薦使用entrySet:

Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for(Map.Entry<Integer, Integer> entry : map.entrySet()){
	System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue())
}

也可以用其他方式:

// 引入 HashMap 類      
import java.util.HashMap;

public class RunoobTest {
    public static void main(String[] args) {
        // 建立 HashMap 物件 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 新增鍵值對
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        // 輸出 key 和 value
        for (Integer i : Sites.keySet()) {
            System.out.println("key: " + i + " value: " + Sites.get(i));
        }
        // 返回所有 value 值
        for(String value: Sites.values()) {
          // 輸出每一個value
          System.out.print(value + ", ");
        }
    }
}

HashSet

HashSet是一個不允許有重複元素的集合。它實現了Set介面:

定義

import java.util.HashSet; // 引入 HashSet 類

HashSet<String> sites = new HashSet<String>();

新增元素

// 引入 HashSet 類      
import java.util.HashSet;

public class RunoobTest {
    public static void main(String[] args) {
    HashSet<String> sites = new HashSet<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Runoob");  // 重複的元素不會被新增
        System.out.println(sites);
    }
}

判斷元素是否存在

使用contains()方法:

// 引入 HashSet 類      
import java.util.HashSet;

public class RunoobTest {
    public static void main(String[] args) {
    HashSet<String> sites = new HashSet<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Runoob");  // 重複的元素不會被新增
        System.out.println(sites.contains("Taobao"));
    }
}

刪除元素

使用remove()方法:

// 引入 HashSet 類      
import java.util.HashSet;

public class RunoobTest {
    public static void main(String[] args) {
    HashSet<String> sites = new HashSet<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Runoob");     // 重複的元素不會被新增
        sites.remove("Taobao");  // 刪除元素,刪除成功返回 true,否則為 false
        System.out.println(sites);
    }
}

刪除所有元素

使用clear()方法:

// 引入 HashSet 類      
import java.util.HashSet;

public class RunoobTest {
    public static void main(String[] args) {
    HashSet<String> sites = new HashSet<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Runoob");     // 重複的元素不會被新增
        sites.clear();  
        System.out.println(sites);
    }
}

計算大小

使用size()方法:

// 引入 HashSet 類      
import java.util.HashSet;

public class RunoobTest {
    public static void main(String[] args) {
    HashSet<String> sites = new HashSet<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Runoob");     // 重複的元素不會被新增
        System.out.println(sites.size());  
    }
}

迭代

使用for-each語句:

// 引入 HashSet 類      
import java.util.HashSet;

public class RunoobTest {
    public static void main(String[] args) {
    HashSet<String> sites = new HashSet<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Runoob");     // 重複的元素不會被新增
        for (String i : sites) {
            System.out.println(i);
        }
    }
}

Iterator

Iterator是迭代器,可以用來迭代ArrayList等集合。迭代器主要有3個方法:

  • next():返回下一個元素,並更新迭代器狀態。
  • hasNext():檢查是否還有元素。
  • remove():刪除元素。

獲取集合的迭代器

// 引入 ArrayList 和 Iterator 類
import java.util.ArrayList;
import java.util.Iterator;

public class RunoobTest {
    public static void main(String[] args) {

        // 建立集合
        ArrayList<String> sites = new ArrayList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");

        // 獲取迭代器
        Iterator<String> it = sites.iterator();

        // 輸出集合中的第一個元素
        System.out.println(it.next());
    }
}

迭代器遍歷集合

// 引入 ArrayList 和 Iterator 類
import java.util.ArrayList;
import java.util.Iterator;

public class RunoobTest {
    public static void main(String[] args) {

        // 建立集合
        ArrayList<String> sites = new ArrayList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");

        // 獲取迭代器
        Iterator<String> it = sites.iterator();

        // 輸出集合中的所有元素
        while(it.hasNext()) {
            System.out.println(it.next());
        }
    }
}

刪除元素

// 引入 ArrayList 和 Iterator 類
import java.util.ArrayList;
import java.util.Iterator;

public class RunoobTest {
    public static void main(String[] args) {
        ArrayList<Integer> numbers = new ArrayList<Integer>();
        numbers.add(12);
        numbers.add(8);
        numbers.add(2);
        numbers.add(23);
        Iterator<Integer> it = numbers.iterator();
        while(it.hasNext()) {
            Integer i = it.next();
            if(i < 10) {  
                it.remove();  // 刪除小於 10 的元素
            }
        }
        System.out.println(numbers);
    }
}

泛型

泛型可以理解為通用型別,不是具體某個型別,而是泛指某些型別。

Java中的泛型標記符如下所示:

  • E - Element (在集合中使用,因為集合中存放的是元素)
  • T - Type(Java 類)
  • K - Key(鍵)
  • V - Value(值)
  • N - Number(數值型別)
  • - 表示不確定的 java 型別

示例:

public class GenericMethodTest {
    // 泛型方法 printArray                         
    public static <E> void printArray(E[] inputArray) {
        // 輸出陣列元素            
        for (E element : inputArray) {
            System.out.printf("%s ", element);
        }
        System.out.println();
    }

    public static void main(String args[]) {
        // 建立不同型別陣列: Integer, Double 和 Character
        Integer[] intArray = {1, 2, 3, 4, 5};
        Double[] doubleArray = {1.1, 2.2, 3.3, 4.4};
        Character[] charArray = {'H', 'E', 'L', 'L', 'O'};

        System.out.println("整型陣列元素為:");
        printArray(intArray); // 傳遞一個整型陣列

        System.out.println("\n雙精度型陣列元素為:");
        printArray(doubleArray); // 傳遞一個雙精度型陣列

        System.out.println("\n字元型陣列元素為:");
        printArray(charArray); // 傳遞一個字元型陣列
    }
}

其中<E>放在方法前表明這是一個泛型方法。可以通過extends限制類型的範圍:

public class MaximumTest
{
   // 比較三個值並返回最大值
   //java.lang.Comparable是個介面,包含一個compareTo()方法
   public static <T extends Comparable<T>> T maximum(T x, T y, T z)
   {                     
      T max = x; // 假設x是初始最大值
      if ( y.compareTo( max ) > 0 ){
         max = y; //y 更大
      }
      if ( z.compareTo( max ) > 0 ){
         max = z; // 現在 z 更大           
      }
      return max; // 返回最大物件
   }
   public static void main( String args[] )
   {
      System.out.printf( "%d, %d 和 %d 中最大的數為 %d\n\n",
                   3, 4, 5, maximum( 3, 4, 5 ) );
 
      System.out.printf( "%.1f, %.1f 和 %.1f 中最大的數為 %.1f\n\n",
                   6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );
 
      System.out.printf( "%s, %s 和 %s 中最大的數為 %s\n","pear",
         "apple", "orange", maximum( "pear", "apple", "orange" ) );
   }
}

除了泛型泛型方法,還可以定義泛型類

public class Box<T> {
   
  private T t;
 
  public void add(T t) {
    this.t = t;
  }
 
  public T get() {
    return t;
  }
 
  public static void main(String[] args) {
    Box<Integer> integerBox = new Box<Integer>();
    Box<String> stringBox = new Box<String>();
 
    integerBox.add(new Integer(10));
    stringBox.add(new String("菜鳥教程"));
 
    System.out.printf("整型值為 :%d\n\n", integerBox.get());
    System.out.printf("字串為 :%s\n", stringBox.get());
  }
}

?是型別萬用字元,比如List<?>在邏輯上是List<String>List<Integer>等的父類:

import java.util.*;
 
public class GenericTest {
     
    public static void main(String[] args) {
        List<String> name = new ArrayList<String>();
        List<Integer> age = new ArrayList<Integer>();
        List<Number> number = new ArrayList<Number>();
        
        name.add("icon");
        age.add(18);
        number.add(314);
 
        getData(name);
        getData(age);
        getData(number);
       
   }
 
   public static void getData(List<?> data) {
      System.out.println("data :" + data.get(0));
   }
}

?也可以通過extends關鍵字來限定類型範圍:

import java.util.*;
 
public class GenericTest {
     
    public static void main(String[] args) {
        List<String> name = new ArrayList<String>();
        List<Integer> age = new ArrayList<Integer>();
        List<Number> number = new ArrayList<Number>();
        
        name.add("icon");
        age.add(18);
        number.add(314);
 
        //getUperNumber(name);//1
        getUperNumber(age);//2
        getUperNumber(number);//3
       
   }
 
   public static void getData(List<?> data) {
      System.out.println("data :" + data.get(0));
   }
   
    //只接受Number及其子類
   public static void getUperNumber(List<? extends Number> data) {
          System.out.println("data :" + data.get(0));
       }
}

List<? extends Number表示只接受Number及其子類(指定上限)。此外還能通過List<? super Number>來表示只能接受Number及其父類(指定下限)。

參考資料:

Java面向物件 https://www.runoob.com/java/java-inheritance.html

Java高階程式設計 https://www.runoob.com/java/java-data-structures.html

Java集合超詳解 https://blog.csdn.net/feiyanaffection/article/details/81394745


所有文章公眾號【測試開發剛哥】首發!

版權申明:本文為博主原創文章,轉載請保留原文連結及作者。