Java集合 之 单列集合

目录

一、集合概述

1、集合

①基础概念

②与数组的对比

③集合分类:

2、集合框架

①基础概念

②三要素

③集合框架继承体系图(重要部分,并非全部)

二、单列集合

1、概述

2、Collection接口

①Collection基础方法

②Collection泛型参数方法补充

3、List接口

①特点:        

②常用方法:

③实现类:

1>  ArrayList

2>  LinkedList

3>  Vector

4、Set接口

①特点:

②常用方法:

③实现类:

1>  HashSet

2>  TreeSet

排序规则

3>  LinkedHashSet


大学生入门:引用数据类型——数组及其易踩坑的点-CSDN博客https://blog.csdn.net/qq_73698057/article/details/149564809?spm=1001.2014.3001.5502

数组特点:

长度固定:

        创建时需要指定长度,并且长度在创建后不可改变

相同数据类型:

        例如int数组只能存储int类型的数据

连续内存分配:

        堆空间为数组开辟的内存是连续的

        导致在插入和删除元素时需要元素整体移动,效率低下

随机访问:

        由于数组中的元素在内存中是连续存储的

        可以通过索引来访问,时间复杂度为O(1)

显而易见

如果我们要存储多个数据类型不一致

或者个数不固定时

数组就无法满足我们的需求了

这时就需要使用 java 提供的集合框架

一、集合概述

1、集合

①基础概念

java中,集合是一种用于存储和操作一组对象的数据结构

它提供了一组接口和类,用于处理和操作对象的集合

②与数组的对比

为了更好地理解集合,我们把集合和数组放在一起来看:

首先他们都可以存储多个元素值

区别在于:

1. 数组的长度是固定的

    集合的长度是可变的

2. 数组中存储的是同一类型的元素

    集合中存储的数组可以是不同类型的

3. 数组可以存放基本类型数据或引用类型变量

    集合中只能存放引用类型变量

4. 数组除了拥有 length属性 和 从Object中继承过来的方法之外,数组对象调用不了其他的属性和方法了

    集合框架由 java.util 包下多个接口和实现类组成,定义并实现了很多方法,功能强大

       

只能存引用类型变量?

那下面这些情况是怎么回事?

collection.add(1);

int a = 1;

collection.add(a);

Integer integer = 1;

collection.add(integer);

        

实际情况是

前两种自动装箱

最后一种直接存储 Integer 对象

所以“集合只能存储引用类型”这个说法是正确的

集合分类:

1.单列集合(Single Column Collection)
        根接口: java.util.Collection
        单列集合是指每个集合元素只包含一个单独的对象,它是集合框架中最简单的形式

Collection接口结构图(重要部分,并非全部)


1.多列集合(Multiple Column Collection)
        根接口: java.util.Map
        多列集合是指每个集合元素由多个列(字段)组成,可以同时存储和操作多个相关的值

Map接口结构图如下(重要部分,并非全部)

2、集合框架

①基础概念

集合框架

        java中用于表示和操作集合的一组类和接口

        位于 java.util 包中

        包括:

                Collection 集合接口

                List            列表接口

                Map           映射接口

                Set             类

                ... ...

        

        目的:

                提供一种通用的方式来存储和操作对象的集合

                无论集合的具体实现方式如何

                用户都可以使用统一的接口和方法来操作集合

怎么理解 集合 集合框架 呢 ?

如果把一个个集合看作一个个收纳盒

那么集合框架就是 收纳指南

上面记录了:

不同类型的收纳盒、

统一的操作标准、

还有现成的使用方法

②三要素

1.接口

        整个集合框架的上层结构,都是用接口进行组织的

        接口中定义了集合中必须要有的基本方法

        通过接口还把集合划分成了几种不同的类型,每一种集合都有自己对应的接口

        

2、实现类

        对于上层使用接口划分好的集合种类,每种集合接口都会有对应的实现类

        每一种接口的实现类很可能有多个,每个的实现方式也各有不同

        

3、数据结构

        每个实现类都实现了接口中所定义的最基本的方法

        例如对数据的存储、检索、操作等方法

        但是不同的实现类,它们存储数据的方式不同,也就是使用的数据结构不同

③集合框架继承体系图(重要部分,并非全部)

二、单列集合

1、概述

        单列集合是指每个集合元素只包含一个单独的对象

        单列集合的根接口是 java.util.Collection 

        根接口下面又有两个子接口:ListSet

如何理解这句话呢?

我们把单列和多列放一起比较

就好比有一个班级花名册

单列集合每一行只有单独的名字信息,而多列集合一行有多个信息:

单列                                        双列

        

再比如说有一列火车

单列火车是这样的:

[苹果车厢] [牛奶车厢] [面包车厢] [鸡蛋车厢]
// 每节车厢只装一种商品

双列火车是这样的:

[苹果-5元车厢] [牛奶-10元车厢] [面包-8元车厢]
// 每节车厢装两种信息:商品名和价格

2、Collection接口

单列集合的父接口

其中定义了单列集合通用的一些方法

Collection接口的实现类都可以使用这些方法

①Collection基础方法

package java.util;
public interface Collection<E> extends Iterable<E> {
   //省略...
    
    //向集合中添加元素 
    boolean add(E e)
    //清空集合中所有的元素。    
    void clear()
    //判断当前集合中是否包含给定的对象。
    boolean contains(Object o)
    //判断当前集合是否为空。
    boolean isEmpty()
    //把给定的对象,在当前集合中删除。
    boolean remove(Object o)
    //返回集合中元素的个数。  
    int size()
    //把集合中的元素,存储到数组中。    
    Object[] toArray()
}

示例:

import java.util.ArrayList;
import java.util.Collection;

public class Test {
    // 集合中 一般 也放 同一种类型数据
    public static void main(String[] args) {
    // 1.接口 引用 = new 实现类(实参);
    Collection coll = new ArrayList();
    if (coll.isEmpty())
    System.out.println("coll is Empty!");
    
    // 2.任何引用类型都可以放入
    // 自动扩容
    coll.add("hello"); //String
    Integer i = 12;
    coll.add(i);
    coll.add(2.3); // Double
    coll.add(1.2F); // Float
    coll.add('a'); // Character
 
    int[] arr = { 1, 2, 3 };
    coll.add(arr); //int[]
 
    // coll.add(new Student());
    // 3.输出 coll.toString()
    System.out.println(coll);
    System.out.println("size: " + coll.size());
    System.out.println("--------------");
 
    // 4.清空 coll
    coll.clear();
    System.out.println(coll);
    
    // 5.判断是否为空
    if (coll.isEmpty())
        System.out.println("coll is Empty!");
    else
        System.out.println("coll is not empty!");
    }
}

此时动手实操的同学会发现代码爆黄线了

为什么呢?

其实是我们的格式有点小问题

区别于之前的书写格式,集合是这样的:

接口类型<存储的数据类型> 接口引用名 = new 实现类<>(构造方法实参);

例: Collection<String> coll = new ArrayList<>();

        

还可以写成:

Collection<String> coll = new ArrayList<String>();

Collection coll = new ArrayList();     

        

需要注意的是,前两种明确了数据类型,就只能存储这一种

第三种可以存储多种,但是一般情况下存储一种数据类型

②Collection泛型参数方法补充

package java.util;
public interface Collection<E> extends Iterable<E> {
   //省略... 
    
    //把一个指定集合中的所有数据,添加到当前集合中    
    boolean addAll(Collection<? extends E> c)

    //判断当前集合中是否包含给定的集合的所有元素。    
    boolean containsAll(Collection<?> c)

    //把给定的集合中的所有元素,在当前集合中删除。    
    boolean removeAll(Collection<?> c)

    //判断俩个集合中是否有相同的元素,如果有当前集合只保留相同元素,如果没有当前集合元素清空    
    boolean retainAll(Collection<?> c)

    //把集合中的元素,存储到数组中,并指定数组的类型  
    <T> T[] toArray(T[] a)

    //返回遍历这个集合的迭代器对象    
    Iterator<E> iterator()
}

示例:

import java.util.ArrayList;
import java.util.Collection;
//泛型方法测试
public class Test03_Element {
    public static void main(String[] args) {
    //1.实例化两个集合对象,专门存放String类型元素
    // 集合实例化对象 固定写法
    Collection<String> c1 = new ArrayList<>();
    Collection<String> c2 = new ArrayList<>();
 
    //2.分别往c1和c2集合中添加元素
    String s1 = "hello";
    String s2 = "world";
    c1.add(s1);
    c1.add(s2);
        
    String s3 = "nihao";
    String s4 = "hello";
    String s5 = "okok";
    c2.add(s3);
    c2.add(s4);
    c2.add(s5);

    System.out.println("c1: " + c1);
    System.out.println("c2: " + c2);
 
    System.out.println("-------------");
 
    //3.将c2集合整体添加到c1中
    c1.addAll(c2);
    System.out.println("c1.size: " + c1.size());
    System.out.println("after addAll(c2), c1: " + c1);
 
    System.out.println("-------------");
 
    //4.判断是否包含指定元素
    boolean f = c1.contains("hello");
    System.out.println("contains hello: " + f);
 
    //5.创建s6对象,判断集合中是否包含该对象
    // 注意: s6的地址 和 "world"地址不一样
    // s6是堆中临时new出来的,"world"存在堆中的字符串常量池中
    String s6 = new String("world");

    // 结果显示true,说明集合contains方法借助equals方法进行比较,而非 ==
    f = c1.contains(s6);
    System.out.println("contains(s6): " + f);
    System.out.println("-------------");
 
    //6.判断是否包含c2对象
    f = c1.containsAll(c2);
    System.out.println("containsAll(c2): " + f);
 
    System.out.println("-------------");
    
    //7.删除指定元素【底层借助equals比较,然后删除】
    f = c1.remove(s6);
    System.out.println("remove(s6): " + f);
    System.out.println("after remove, c1: " + c1);
 
    System.out.println("-------------"); 
 
    //8.删除c2整个集合【底层实现:遍历c2,逐个元素equals比较,然后删除】
    f = c1.removeAll(c2);
    System.out.println("removeAll(c2): " + f);
    System.out.println("after remove, c1: " + c1);
    }
}

3、List接口

继承了 Collection 接口

①特点:        

        ——有序集合

        ——带索引的集合,可以通过索引精确查找对应元素

        ——可以存放重复元素(包括null)

        ——默认尾部添加元素

②常用方法:

除了从 Collection 中继承过来的方法,除此之外还有:

//返回集合中指定位置的元素。
E get(int index);

//用指定元素替换集合中指定位置的元素,并返回被替代的旧元素。
E set(int index, E element);

//将指定的元素,添加到该集合中的指定位置上。
void add(int index, E element);

//从指定位置开始,把另一个集合的所有元素添加进来
boolean addAll(int index, Collection<? extends E> c);

//移除列表中指定位置的元素, 并返回被移除的元素。
E remove(int index);

//查收指定元素在集合中的所有,从前往后查到的第一个元素(List集合可以重
复存放数据)
int indexOf(Object o);

//查收指定元素在集合中的所有,从后往前查到的第一个元素(List集合可以重
复存放数据)
int lastIndexOf(Object o);

//根据指定开始和结束位置,截取出集合中的一部分数据
List<E> subList(int fromIndex, int toIndex);

示例:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Test {
 public static void main(String[] args) {
    //1.创建List集合对象
    List<String> list = new ArrayList<>();
    
    //2.添加元素,默认尾部添加
    list.add("hello1");
    list.add("hello2");
    list.add("hello3");
    list.add("hello1");
    
    System.out.println(list);
    
    //3.指定位置添加元素
    // add(int index,String s) 
    list.add(1, "world");
    System.out.println(list);

    //4.删除索引位置为2的元素
    boolean f = list.remove(2);
    System.out.println("remove(2): " + f);
    System.out.println("after remove: " + list);

    //5.修改指定位置元素
    list.set(0, "briup");
    System.out.println(list);

    //6.借助get方法遍历集合
    for (int i = 0; i < list.size(); i++) {
        System.out.println(list.get(i));    
    }
    System.out.println("-----------------");

    //7.使用foreach遍历
    for(Object obj : list){
        System.out.println(obj);
    }
    System.out.println("-----------------");
    
    //8.使用迭代器遍历
    Iterator<String> it = list.iterator();
    while(it.hasNext()){
        String str = it.next();
        System.out.println(str);
    }
  }
}

③实现类:

1>  ArrayList

是 List 的一个实现类

是最常用的一种 List 类型集合

extends AbstractList<E> extends AbstractCollection<E>

特点:

        1. ArrayList集合底层是数组,查询快,增删慢

            适用业务场景:查询功能多,增删功能少

            eg:学生管理系统

        2. ArrayList集合线程不安全

代码示例与 LinkedList 放在一起对比

2>  LinkedList

实现了List接口

extends AbstractSequentialList<E> extends AbstractList<E>

特点:

        1. LinkedList 集合底层是双向链表,查询慢,增删快

            适用业务场景:增删功能多,查询功能少

            eg:浏览器的前进后退

        2. LinkedList 集合线程也不安全

特点验证:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        //操作集合的次数
        final int NUM = 100000;

        //1.实例化集合对象
        List<String> list = new ArrayList<>();
        //List<String> list = new LinkedList<>();

        //2.开启计时,往集合种放入 100000 个元素
        long start1 = System.currentTimeMillis();
        for (int i = 0; i < NUM; i++) {
            list.add(0,"hello"+i);
        }
        long end1 = System.currentTimeMillis();
    
        //3.输出时长
        System.out.println(list.getClass().getSimpleName()+"插入"+NUM+"条数据耗时"+(end1-start1)+"毫秒");
    
        //4.开启计时,从集合种取 100000 个元素
        long start2 = System.currentTimeMillis();
        for(int i = 0; i < list.size(); i++){
            list.get(i);
        }
        long end2 = System.currentTimeMillis();
    
        //5.输出时长
        System.out.println(list.getClass().getSimpleName()+"检索"+NUM+"条数据耗时"+(end2-start2)+"毫秒");
    }
}

//运行效果:
//根据电脑的当前情况,每次运行的结果可能会有差异
//以下是我的电脑运行的实验结果

ArrayList插入100000条数据耗时508毫秒
ArrayList检索100000条数据耗时2毫秒
LinkedList插入100000条数据耗时22毫秒
LinkedList检索100000条数据耗时17709毫秒

System.currentTimeMillis();

//获取当前时刻的时间戳

3>  Vector

实现了 List 接口

extends AbstractList<E> extends AbstractCollection<E>

特点:

        1. Vector 集合底层是数组,查询快,增删慢

        2. Vector 集合多线程安全,效率低

4、Set接口

继承了 Collection 接口

①特点:

        ——无序集合,不按 add 顺序添加元素

        ——不带下标(索引)

        ——元素不能重复

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Test {
    public static void main(String[] args){
        //1.实例化Set集合,指向HashSet实现类对象
        Set<String> set = new HashSet<>();
    
        set.add("hello1");
        set.add("hello2");
        set.add("hello3");
        set.add("hello4");
        set.add("hello5"); //添加失败 重复元素
        set.add("hello5"); //添加失败 重复元素
    
        //加强for循环遍历
        for(String obj : set){
            System.out.println(obj);
        }

        System.out.println("-----------------");

        //迭代器遍历
        Iterator<String> it = set.iterator();
        while(it.hasNext()){
            Object obj = it.next();
            System.out.println(obj);
        }
    }
}

//输出结果:
hello1
hello4
hello5
hello2
hello3
----------
省略...

②常用方法:

基本都是Collection继承过来的,这里就不再赘述

③实现类:

1>  HashSet

底层是哈希表

extends AbstractSet<E> implements Set<E>

特点:

        1. 无序性:存储顺序和插入顺序无关

        2. 唯一性:元素不重复,null也只能存一个

        3. 高效性:哈希表的特点

需要注意的是,由于HashSet没有重写 equals方法 和 hashCode方法

所以存储 数据相同的自定义类的对象 时会认为它们是不同的

比如:

import java.util.*;

class Student {
    private String name;
    private int age;
    
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // 注意:这里没有重写 equals 和 hashCode 方法
    
    @Override
    public String toString() {
        return "Student{name='" + name + "', age=" + age + "}";
    }
}

public class HashSetDuplicateExample {
    public static void main(String[] args) {
        Set<Student> set = new HashSet<>();
        
        // 添加四个"相同"的Student对象
        set.add(new Student("Alice", 20));
        set.add(new Student("Alice", 20));
        set.add(new Student("Alice", 20));
        set.add(new Student("Alice", 20));
        
        System.out.println("HashSet大小: " + set.size()); // 输出 4
        System.out.println("HashSet内容: " + set);
    }
}

所以要往 HashSet 集合存储自定义类

一定要记得重写自定义类中的equals方法和hashCode方法

2>  TreeSet

底层是二叉树

TreeSet是SortedSet(Set接口的子接口)的实现类

特点:

        1. 有序性:插入的元素会自动排序

        2. 唯一性:元素不重复,null也只有一个

        3. 高效性:二叉树的特点

入门案例一:

import java.util.Set;
import java.util.TreeSet;

public class Test{
    public static void main(String[] args){
        //1.实例化集合对象
        Set<Integer> set = new TreeSet<>();
 
        //2.添加元素
        set.add(3);
        set.add(5);
        set.add(1);
        set.add(7);
    
        //3.遍历
        for(Integer obj : set) {
            System.out.println(obj);
        }    
    }
}

//输出结果:
1
3
5
7

截止这里一切都没有问题,我们继续往下看

入门案例二:

import java.util.Set;
import java.util.TreeSet;

class Person {
    private String name;
    private int age;
 
    public Person() {}
    public Person(String name, int age) {
    this.name = name;
    this.age = age;
    }
 
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public int getAge() {
    return age;
    }
    public void setAge(int age) {
    this.age = age;
    }
 
    @Override
    public String toString() {
    return "Person [name=" + name + ", age=" + age + "]";
    }
}


public class Test_Person {
    public static void main(String[] args) {
        //1.实例化TreeSet
        Set<Person> set = new TreeSet<>();

        //2.添加元素
        set.add(new Person("zs",21));
        set.add(new Person("ls",20));
        set.add(new Person("tom",19));
 
        //3.遍历集合
        for (Person person : set) {
        System.out.println(person);
        }
    }
}

//程序运行,提示异常,具体如下:
Exception in thread "main" java.lang.ClassCastException: 
包名.Person cannot be cast to java.lang.Comparable
 at java.util.TreeMap.compare(TreeMap.java:1290)
 at java.util.TreeMap.put(TreeMap.java:538)
 at java.util.TreeSet.add(TreeSet.java:255)
 at 
包名.Test_Person.main(Test_Person.java:41)

看起来似乎没有问题啊

为什么会报错呢?

我们看一下报错原因:

ClassCastException:Person cannot be cast to java.lang.Comparable

原来是我们自定义的类没有实现 Comparable 接口

为什么会这样呢?

这就不得不引入新的知识点了:

排序规则

由于TreeSet是一个有序集合,那么想要有序必然要存在一定的规则

有两种方式

1、自然排序

        如果一个类实现了Comparable接口

        并且重写了compareTo方法,那么这个类对象就可以进行排序了。

        

        compareTo方法说明:

                返回值:int

                        小于0:当前对象小,this.value < o.value

                        等于0:当前对象等于 this.value = o.value

                        大于0:当前对象大  this.value > o.value

                调用者:当前对象的参数

                实际参数:要比较的对象参数

                调用方式:this.value.compareTo(o.value);

                作用:

                        元素插入过程:先排序后去重

                        当TreeSet插入元素时会调用compareTo方法

                        如果方法返回-1,先插入this,o放后面
                        如果方法返回0,两个元素相等,只插入一个元素
                        如果方法返回1,先插入o,this放后面

2、比较器排序

        如果Student不是自定义类,而是第三方提供的类

        我们不可以修改源码,就可以使用比较器排序

        

        实现:

                1、创建一个实现了 Comparator 接口的类
                2、重写里面的 compare() 方法
                3、创建一个
TreeSet(因为有序所以才排序)类对象时,将比较器对象作为参数传递给构造函数

        compare方法说明:

                int result = compare(o1,o2);

                ——result的值大于0,表示升序

                ——result的值小于0,表示降序

                ——result的值等于0,表示元素相等,不能插入

                由于返回值是int,处理非int类型时大致有三种情况:

①使用包装类的compare方法

// 比较double类型
public int compare(Student s1, Student s2) {
    return Double.compare(s1.getScore(), s2.getScore());  // 升序
    // return Double.compare(s2.getScore(), s1.getScore());  // 降序
}

// 比较float类型
public int compare(Student s1, Student s2) {
    return Float.compare(s1.getGPA(), s2.getGPA());
}

// 比较long类型
public int compare(Student s1, Student s2) {
    return Long.compare(s1.getId(), s2.getId());
}

②手动转换比较结果

// double比较的手动实现
public int compare(Student s1, Student s2) {
    double diff = s1.getScore() - s2.getScore();
    if (diff < 0) return -1;
    if (diff > 0) return 1;
    return 0;
}

// 但这种方式不推荐,因为可能存在精度问题

③其他类型

public class StudentComparator implements Comparator<Student> {
    
    @Override
    public int compare(Student s1, Student s2) {
        // 比较字符串
        int nameCompare = s1.getName().compareTo(s2.getName());
        if (nameCompare != 0) return nameCompare;
        
        // 比较double分数
        int scoreCompare = Double.compare(s2.getScore(), s1.getScore()); // 降序
        if (scoreCompare != 0) return scoreCompare;
        
        // 比较int年龄
        return Integer.compare(s1.getAge(), s2.getAge());
    }
}

       

注意:

        如果自然排序和比较器排序同时存在

        优先使用比较器排序

案例展示:

public class Teacher implements Comparable<Teacher>{

    private int id;
    private String name;
    private int age;
    
    public Teacher() {
    }
    public Teacher(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Teacher [id=" + id + ", name=" + name + ", age=" + age + "]";
    }

    @Override
    public int compareTo(Teacher o) {
        int num = this.name.compareTo(o.name);
        if(num == 0){
            num = this.age - o.age;
        }
        if(num == 0){
            num = this.id - o.id;
        }
        return num;
    }
}

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class TestTeacher {
    public static void main(String[] args) {
        //自然排序,Comparable接口
        Teacher t1 = new Teacher(001,"alan", 18);
        Teacher t2 = new Teacher(002,"tom", 19);
        Teacher t3 = new Teacher(003,"tom", 20);
        Teacher t4 = new Teacher(004,"alan", 18);
        Teacher t5 = new Teacher(005,"jack", 18);
        Set<Teacher> set = new TreeSet<>();
        System.out.println("自然排序:");
        set.add(t1);
        set.add(t2);
        set.add(t3);
        set.add(t4);
        set.add(t5);
        for(Teacher t : set){
            System.out.println(t);
        }

        //比较器排序,Comparator接口
        Comparator<Teacher> comparator = new Comparator<Teacher>() {
            @Override
            public int compare(Teacher t1, Teacher t2){ 
                int num = t1.getName().compareTo(t2.getName());
                if(num == 0){ 
                    num = t1.getAge() - t2.getAge();
                }
                if(num == 0){
                    num = t1.getId() - t2.getId();
                }
                return num;
            }
        };
        Set<Teacher> set2 = new TreeSet<>(comparator);
        System.out.println("比较器排序:");
        set2.add(t1);
        set2.add(t2);
        set2.add(t3);
        set2.add(t4);
        set2.add(t5);
        for(Teacher t : set2){
            System.out.println(t);
        }
    }
}
3>  LinkedHashSet

底层是链表 + 哈希表

父类 HashSet 所以具有父类唯一、高效的优点
接口 Set     保持元素的插入顺序,不会自动排序

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

public class Test074_LinkedHashSet {
    public static void main(String[] args) {
    // 1.实例化LinkedHashSet
    Set<String> set = new LinkedHashSet<>();

    // 2.添加元素
    set.add("bbb");
    set.add("aaa");
    set.add("abc");
    set.add("bbc");
    set.add("abc");

    // 3.迭代器遍历
    Iterator<String> it = set.iterator();
    while (it.hasNext()) {
    System.out.println(it.next());
    }
  }
}

//运行结果:
bbb
aaa
abc
bbc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值