JAVA-接口,异常

学习目标
掌握接口的意义和使用
为什么要用接口
计算机中的数据可以通过USB传输到外部存储器中,USB具有数据传输功能,存储器具有数据存储功能,将USB和存储器分别定义为抽象类,U盘可以同时继承USB和存储器么?
抽象类表示的是一种继承关系,一个类只能使用一次继承关系,这样限制了类的多重体现 。如何解决这个问题呢?使用接口。

接口的特点:
Java是单继承的语言,利用接口可以模拟多继承;
接口是对抽象类的进一步抽象,是方法声明和常量的定义集合;
接口是一种行为规范,是一种“契约”;
接口不可以被实例化
实现类必须实现接口的所有方法
实现类可以实现多个接口
接口中的变量都是静态常量

为什么接口可以多继承,而类不可以?
如果有两个父类,两个父类里有一个相同的方法,那么作为子类应该怎么继承这个方法?父类1的还是父类2的?但是实现多个接口则没问题,因为不管哪个接口,调用的都是同一个实现,因为只有方法名!而且单继承的目的之一,就是降低复杂度,减少维护难度。

接口的使用
接口的定义格式如下:
<访问符> interface 接口名 {
[访问符] <返回类型> 方法名([参数列表]);

}

定义一个接口MultiInterface.java,代码如下:
public interface MultiInterface {
public static final double PI = 3.1415926;
public void callArea();
default void before(){ //仅限于JDK1.8以后可使用
System.out.println(“现在开始计算:”);
}
}

注意:在定义接口的时候,接口中的所有方法和常量自动定义为public。 接口中定义的变量默认是public static final 型,且必须赋初值。
从JDK1.8开始可以使用default关键字来定义一个默认的方法来扩展接口,default关键字修饰的默认方法可以直接调用,不用子类去实现。

编码实操
先声明USB接口:其中规定了要实现USB接口就必须实现接口规定实现的read( )和write( )这两个方法。
interface USB {
void read();
void write();
}
然后在写一个U盘类UDisk和一个键盘类Keyboard,这两个类都去实现USB接口。(实现其中的方法)
class UDisk implements USB {
    @Override
    public void read() {
        System.out.println(“U盘正在通过USB功能读取数据”);
    }
    @Override
    public void write() {
        System.out.println(“U盘正在通过USB功能写入数据”);
    }
}

class Keyboard implements USB {
    @Override
    public void read() {
        System.out.println(“键盘正在通过USB功能读取数据”);
    }
    @Override
    public void write() {
        System.out.println(“键盘正在通过USB功能写入数据”);
    }
}

测试类:
public class Main {
    public static void main(String[] args) {
        //生成一个实现可USB接口(标准)的U盘对象
       UDisk udisk = new UDisk();
        //调用U盘的read( )方法读取数据
        udisk.read();
        //调用U盘的write( )方法写入数据
        udisk.write();
        //生成一个实现可USB接口(标准)的键盘对象
       Keyboard keyboard = new Keyboard();
        //调用键盘的read( )方法读取数据
       keyboard.read();
        //调用键盘的write( )方法写入数据
       keyboard.write();
    }
}

练习题

  1. 下面关于Java接口的说法错误的是( )。
    A. 一个Java接口是一些方法特征的集合,但没有方法的实现
    B. Java接口中定义的方法在不同的地方被实现,可以具有完全不同的行为
    C. Java接口中可以声明私有成员
    D. Java接口不能被实例化

  2. 在Java接口中定义常量,下面语法错误的是( )。
    A. static int MALE = 1;
    B. final int MALE = 1;
    C. int MALE = 1;
    D. private int MALE = 1;

  3. 在Java接口中,下列选项中属于有效的方法声明是( )(多选)。
    A. public void aMethod();
    B. void aMethod();
    C. void aMethod(){}
    D. private void aMethod();

  4. 给定如下Java程序代码,在横线处加入( )语句,可以使这段代码编译通过(多选)。
    interface Parent{
    public int count(int i);
    }
    public class Test implements Parent {
    public int count(int i){
    return i % 9;
    }
    public static void main(String[] args){
    ________________
    int i = p.count(20);
    }
    }
    A. Test p = new Test();
    B. Parent p = new Test();
    C. Parent p = new Parent();
    D. Test p = new Parent();

答案:1.C 2.D 3.AB 4.AB

异常
学习目标
掌握异常的处理方法
什么是异常
异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。

比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error;如果你用System.out.println(11/0),那么你是因为你用0做了除数,会抛出 java.lang.ArithmeticException 的异常。
异常发生的原因有很多,通常包含以下几大类:
用户输入了非法数据。
要打开的文件不存在。
网络通信时连接中断,或者JVM内存溢出。

要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常:
检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

异常处理
异常处理的流程如下:

Java标准库内建了一些通用的异常,这些类以Throwable为顶层父类。
Throwable又派生出Error类和Exception类。
错误:Error类以及他的子类的实例,代表了JVM本身的错误。错误不能被程序员通过代码处理,Error很少出现。因此,程序员应该关注Exception为父类的分支下的各种异常类。
异常:Exception以及他的子类,代表程序运行时发送的各种不期望发生的事件。可以被Java异常处理机制使用,是异常处理的核心。
Java异常的分类和类结构图:

Java的异常处理是通过5个关键字来实现的:try、catch、 finally、throw、throws。
捕获异常
try:执行可能产生异常的代码。
catch:捕获异常。
finally:无论是否发生异常,代码总能执行。

public void method(){
try {
// 代码段 1
// 产生异常的代码段 2
// 代码段 3
} catch (异常类型 ex) {
// 对异常进行处理的代码段4
}
// 代码段5
}

异 常 类 型
说 明

Exception
异常层次结构的父类

ArithmeticException
算术错误情形,如以零作除数

ArrayIndexOutOfBoundsException
数组下标越界

NullPointerException
尝试访问 null 对象成员

ClassNotFoundException
不能加载所需的类

IllegalArgumentException
方法接收到非法参数

ClassCastException
对象强制类型转换出错

NumberFormatException
数字格式转换异常,如把"abc"转换成数字

异常的处理示例:
import java.util.Scanner;
/**

  • 使用try-catch-finally进行异常处理。
    */
    public class Test4 {
    public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    System.out.print(“请输入被除数:”);
    try {
    int num1 = in.nextInt();
    System.out.print(“请输入除数:”);
    int num2 = in.nextInt();
    System.out.println(String.format("%d / %d = %d",
    num1, num2, num1/ num2));
    } catch (Exception e) {
    System.err.println(“出现错误:被除数和除数必须是整数,” +
    “除数不能为零。”);
    System.out.println(e.getMessage());
    //System.exit(1); // finally语句块不执行的唯一情况
    } finally {
    System.out.println(“感谢使用本程序!”);
    }
    }
    }

多重异常示例:
import java.util.Scanner;
import java.util.InputMismatchException;
/**

  • 多重catch块。
    */
    public class Test7 {
    public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    System.out.print(“请输入被除数:”);
    try {
    int num1 = in.nextInt();
    System.out.print(“请输入除数:”);
    int num2 = in.nextInt();
    System.out.println(String.format("%d / %d = %d",
    num1, num2, num1/ num2));
    } catch (InputMismatchException e) {
    System.err.println(“被除数和除数必须是整数。”);
    } catch (ArithmeticException e) {
    System.err.println(“除数不能为零。”);
    } catch (Exception e) {
    System.err.println(“其他未知异常。”);
    } finally {
    System.out.println(“感谢使用本程序!”);
    }
    }
    }
    多重异常的执行规则:
    排列catch 语句的顺序:先子类后父类
    发生异常时按顺序逐个匹配
    只执行第一个与异常类型匹配的catch语句

声明异常
throws:声明方法可能要抛出的各种异常。
如果一个方法没有捕获到一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。
抛出异常
throw:手动抛出异常。
例子:
public class Person {
private String name = “”; // 姓名
private int age = 0; // 年龄
private String sex = “男”; // 性别
public void setSex(String sex) throws Exception {
if (“男”.equals(sex) || “女”.equals(sex))
this.sex = sex;
else {
throw new Exception(“性别必须是"男"或者"女"!");
}
}
}

集合
学习目标
掌握集合的意义
掌握常用集合的使用
掌握泛型集合的意义和使用
为什么要使用集合
假设需要存储一个班20个学生的信息,如何实现?
使用数组:

假设来了一个新同学,如何把新同学的信息添加到数组里?
假设需要存储所有学生的姓名和成绩,并一一对应,如何存储在一个数组里?
上述问题,使用数组实现比较困难。可以使用Java的集合框架。

集合基础
Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中。

Java集合按照其存储结构可以分为两大类,即单列集合Collection和双列集合Map。
Collection是单列集合类的根接口,其有两个重要子接口 List 和Set。
List接口的主要类有 ArrayList 和 LinkedList。
Set接口的主要类有 HashSet和TreeSet。
Map接口的主要实现类有HashMap 和 TreeMap

各接口的特点:
List 接口存储一组不唯一,有序(插入顺序)的对象
Set 接口存储一组唯一,无序的对象
Map接口存储一组键值对象,提供key到value的映射

ArrayList实现了长度可变的数组,在内存中分配连续的空间。遍历元素和随机访问元素的效率比较高。

LinkedList采用链表存储方式。插入、删除元素时效率比较高。

遍历ArrayList集合:
import java.util.*;

public class Test{
public static void main(String[] args) {
List list=new ArrayList();
list.add(“Hello”);
list.add(“World”);
list.add(“HAHAHAHA”);
//第一种遍历方法使用foreach遍历List
for (String str : list) {//也可以改写for(int i=0;i<list.size();i++)这种形式
System.out.println(str);
}

 //第二种遍历,把链表变为数组相关的内容进行遍历
 String[] strArray=new String[list.size()];
 list.toArray(strArray);

//这里也可以改写为 foreach(String str:strArray)这种形式
for(int i=0;i<strArray.length;i++) {
System.out.println(strArray[i]);
}

//第三种遍历 使用迭代器进行相关遍历     
 Iterator<String> ite=list.iterator();
 while(ite.hasNext())//判断下一个元素之后有值
 {
     System.out.println(ite.next());
 }

}
}

遍历 Map:
import java.util.*;

public class Test{
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put(“1”, “value1”);
map.put(“2”, “value2”);
map.put(“3”, “value3”);

  //第一种:普遍使用,二次取值
  System.out.println("通过Map.keySet遍历key和value:");
  for (String key : map.keySet()) {
   System.out.println("key= "+ key + " and value= " + map.get(key));
  }
  
  //第二种
  System.out.println("通过Map.entrySet使用iterator遍历key和value:");
  Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
  while (it.hasNext()) {
   Map.Entry<String, String> entry = it.next();
   System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
  }
  
  //第三种:推荐,尤其是容量大时
  System.out.println("通过Map.entrySet遍历key和value");
  for (Map.Entry<String, String> entry : map.entrySet()) {
   System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
  }

  //第四种
  System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
  for (String v : map.values()) {
   System.out.println("value= " + v);
  }
 }

}

List

List集合代表一个有序集合,集合中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。
ArrayList实现了长度可变的数组,在内存中分配连续的空间。遍历元素和随机访问元素的效率比较高。
LinkedList采用链表存储方式。插入、删除元素时效率比较高。
ArrayList
使用ArrayList存储元素:
//创建四个狗狗对象 …
List dogs = new ArrayList();
dogs.add(ououDog);
dogs.add(yayaDog);
dogs.add(meimeiDog);
dogs.add(2, feifeiDog); // 添加feifeiDog到指定位置
System.out.println(“共计有” + dogs.size() + “条狗狗。”);
System.out.println(“分别是:”);
for (int i = 0; i < dogs.size(); i++) {
Dog dog = (Dog) dogs.get(i);
… …
}

使用ArrayList移除、判断元素:
import java.util.ArrayList;
import java.util.List;

/**

  • 测试ArryList的remove()、contains()方法
    */
    public class Test2 {
    public static void main(String[] args) {
    // 1、创建多个狗狗对象
    Dog ououDog = new Dog(“欧欧”, “雪娜瑞”);
    Dog yayaDog = new Dog(“亚亚”, “拉布拉多”);
    Dog meimeiDog = new Dog(“美美”, “雪娜瑞”);
    Dog feifeiDog = new Dog(“菲菲”, “拉布拉多”);
    // 2、创建ArrayList集合对象并把多个狗狗对象放入其中
    List dogs = new ArrayList();
    dogs.add(ououDog);
    dogs.add(yayaDog);
    dogs.add(meimeiDog);
    dogs.add(2, feifeiDog);
    // 3、输出删除前集合中狗狗的数量
    System.out.println(“删除之前共计有” + dogs.size() + “条狗狗。”);
    // 4、删除集合中第一个狗狗和feifeiDog狗狗
    dogs.remove(0);
    dogs.remove(feifeiDog);
    // 5、显示删除后集合中各条狗狗信息
    System.out.println("\n删除之后还有" + dogs.size() + “条狗狗。”);
    System.out.println(“分别是:”);
    for (int i = 0; i < dogs.size(); i++) {
    Dog dog = (Dog) dogs.get(i);
    System.out.println(dog.getName() + “\t” + dog.getStrain());
    }
    //6、判断集合中是否包含指定狗狗信息
    if(dogs.contains(meimeiDog))
    System.out.println("\n集合中包含美美的信息");
    else
    System.out.println("\n集合中不包含美美的信息");
    }
    }

List接口常用方法:
方法名
说 明

boolean add(Object o)
在列表的末尾顺序添加元素,起始索引位置从0开始

void add(int index,Object o)
在指定的索引位置添加元素。索引位置必须介于0和列表中元素个数之间

int size()
返回列表中的元素个数

Object get(int index)
返回指定索引位置处的元素。取出的元素是Object类型,使用前需要进行强制类型转换

boolean contains(Object o)
判断列表中是否存在指定元素

boolean remove(Object o)
从列表中删除元素

Object remove(int index)
从列表中删除指定位置元素,起始索引位置从0开始

LinkedList
使用LinkedList存储元素:
// 创建多个狗狗对象…
LinkedList dogs = new LinkedList();
dogs.add(ououDog);
dogs.add(yayaDog);
dogs.addLast(meimeiDog);
dogs.addFirst(feifeiDog);

Dog dogFirst= (Dog)dogs.getFirst();//获取集合第一条信息
System.out.println(“第一条狗狗昵称是”+dogFirst.getName() );

Dog dogLast= (Dog)dogs.getLast();//获取集合最后一条信息
System.out.println(“最后一条狗狗昵称是”+dogLast.getName());

dogs.removeFirst();//删除集合第一条信息
dogs.removeLast(); //删除集合最后一条信息

LinkedList的特殊方法:
方法名
说 明

void addFirst(Object o)
在列表的首部添加元素

void addLast(Object o)
在列表的末尾添加元素

Object getFirst()
返回列表中的第一个元素

Object getLast()
返回列表中的最后一个元素

Object removeFirst()
删除并返回列表中的第一个元素

Object removeLast()
删除并返回列表中的最后一个元素

Vector和ArrayList的异同
实现原理、功能相同,可以互用。
主要区别:
Vector线程安全,ArrayList重速度轻安全,线程非安全
长度需增长时,Vector默认增长一倍,ArrayList增长50%

迭代器Iterator
如何遍历一个Map集合?
方法一:使用迭代器Iterator
Set keys=dogMap.keySet(); //取出所有key的集合
Iterator it=keys.iterator(); //获取Iterator对象
while(it.hasNext()){
String key=(String)it.next(); //取出key
Dog dog=(Dog)dogMap.get(key); //根据key取出对应的值
System.out.println(key+"\t"+dog.getStrain());
}
方法二:使用for循环。

例子:使用HashMap存储和处理信息。
企鹅类:
/**

  • 宠物企鹅
    */
    public class Penguin {
    String name = “无名氏”; // 昵称
    int health = 100; // 健康值
    int love = 0; // 亲密度
    String sex = “Q仔”; // 性别

    /**

    • 两个参数构造方法。
      */
      public Penguin(String name, String sex) {
      this.name = name;
      this.sex = sex;
      }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public String getSex() {
    return sex;
    }

    public void setSex(String sex) {
    this.sex = sex;
    }

}
测试类:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**

  • 使用HashMap存储和处理企鹅信息。
    */
    public class Test3 {
    public static void main(String[] args) {

     // 1、创建多个企鹅对象
     Penguin ououPenguin = new Penguin("欧欧", "Q仔");
     Penguin yayaPenguin = new Penguin("亚亚", "Q妹");
     Penguin meimeiPenguin = new Penguin("美美", "Q妹");
     Penguin feifeiPenguin = new Penguin("菲菲", "Q妹");
    
     /* 2、创建HashMap集合对象并把多个企鹅对象放入其中*/
     
     Map penguinMap=new HashMap();
     penguinMap.put(ououPenguin.getName(),ououPenguin);
     penguinMap.put(yayaPenguin.getName(),yayaPenguin);
     penguinMap.put(meimeiPenguin.getName(),meimeiPenguin);
     penguinMap.put(feifeiPenguin.getName(),feifeiPenguin);
     /*3、通过迭代器依次输出集合中所有狗狗的信息*/
     System.out.println("使用Iterator遍历,所有企鹅的昵称和品种分别是:");
     Set keys=penguinMap.keySet();//取出所有key的集合
     Iterator it=keys.iterator();//获取Iterator对象
     while(it.hasNext()){
     	String key=(String)it.next();  //取出key
     	Penguin penguin=(Penguin)penguinMap.get(key);  //根据key取出对应的值
     	System.out.println(key+"\t"+penguin.getSex());
     }
    

    }
    }

泛型集合
为什么要用泛型
举个例子:

上述代码在编译期没有问题,但在运行期,将会报错。因为List的add方法的参数为Object,所以如果程序员在不知道List类型时,通过强转获值,这时就会报错了。
使用泛型,将会解决这个问题。

如上两个截图所示,当声明List所能装载的类型后,List的add方法就只能装载指定的类型,不然在编译期便会报错。而且在获值时,不再需要强制转换。
使用泛型的优点
Java语言引入泛型的好处是安全简单。泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。
类型安全。泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。
消除强制类型转换。泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。
潜在的性能优势。泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来可能。由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。
泛型的使用
泛型使用示例一:
/* 1、创建多个狗狗对象*/
Dog ououDog = new Dog(“欧欧”, “雪娜瑞”);
Dog yayaDog = new Dog(“亚亚”, “拉布拉多”);
Dog meimeiDog = new Dog(“美美”, “雪娜瑞”);
Dog feifeiDog = new Dog(“菲菲”, “拉布拉多”);
/* 2、创建ArrayList集合对象并把多个狗狗对象放入其中*/
List dogs = new ArrayList();//标记元素类型
dogs.add(ououDog);
dogs.add(yayaDog);
dogs.add(meimeiDog);
dogs.add(2, feifeiDog); // 添加feifeiDog到指定位置
//dogs.add(“hello”); //出现编译错误,元素类型不是Dog。
/* 3、 显示第三个元素的信息*/
Dog dog3 = dogs.get(2); //无需类型强制转换
System.out.println(“第三个狗狗的信息如下:”);
System.out.println(dog3.getName() + “\t” + dog3.getStrain());
/4、使用foreach语句遍历dogs对象/
System.out.println("\n所有狗狗的信息如下:");
for(Dog dog:dogs){//无需类型强制转换
System.out.println(dog.getName() + “\t” + dog.getStrain());
}
泛型使用示例二:
Dog ououDog = new Dog(“欧欧”, “雪娜瑞”);
Dog yayaDog = new Dog(“亚亚”, “拉布拉多”);
Dog meimeiDog = new Dog(“美美”, “雪娜瑞”);
Dog feifeiDog = new Dog(“菲菲”, “拉布拉多”);
/* 2、创建Map集合对象并把多个狗狗对象放入其中*/
Map<String,Dog> dogMap=new HashMap<String,Dog>();
dogMap.put(ououDog.getName(),ououDog);
dogMap.put(yayaDog.getName(),yayaDog);
dogMap.put(meimeiDog.getName(),meimeiDog);
dogMap.put(feifeiDog.getName(),feifeiDog);
/3、通过迭代器依次输出集合中所有狗狗的信息/
System.out.println(“使用Iterator遍历,所有狗狗的昵称和品种分别是:”);
Set keys=dogMap.keySet();//取出所有key的集合
Iterator it=keys.iterator();//获取Iterator对象
while(it.hasNext()){
String key=it.next(); //取出key
Dog dog=dogMap.get(key); //根据key取出对应的值
System.out.println(key+"\t"+dog.getStrain());
}
///使用foreach语句输出集合中所有狗狗的信息
for(String key:keys){
Dog dog=dogMap.get(key); //根据key取出对应的值
System.out.println(key+"\t"+dog.getStrain());
}
/
Map
Map接口专门处理键值映射数据的存储,可以根据键实现对值的操作,最常用的实现类是HashMap。
使用HashMap存储数据:
Map countries = new HashMap();
countries.put(“CN”, “中华人民共和国”);
countries.put(“RU”, “俄罗斯联邦”);
countries.put(“FR”, “法兰西共和国”);
countries.put(“US”, “美利坚合众国”);

String country = (String) countries.get(“CN”);//获取指定元素的值
//… …

System.out.println(“Map中共有”+countries.size() +“组数据”);//获取元素个数

countries.remove(“FR”);//删除指定元素
System.out.println(“Map中包含FR的key吗?” +
countries.containsKey(“FR”));

System.out.println( countries.keySet() ) ;//显示键集
System.out.println( countries.values() );//显示值集
System.out.println( countries );//显示键值对集

Map接口常用方法:
方法名
说 明

Object put(Object key, Object val)
以“键-值对”的方式进行存储

Object get (Object key)
根据键返回相关联的值,如果不存在指定的键,返回null

Object remove (Object key)
删除由指定的键映射的“键-值对”

int size()
返回元素个数

Set keySet ()
返回键的集合

Collection values ()
返回值的集合

boolean containsKey (Object key)
如果存在由指定的键映射的“键-值对”,返回true

Hashtable和HashMap的异同:
实现原理、功能相同,可以互用。
主要区别:
Hashtable继承Dictionary类,HashMap实现Map接口
Hashtable线程安全,HashMap线程非安全
Hashtable不允许null值,HashMap允许null值

注意:开发过程中,最好使用ArrayList和HashMap。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值