[Java][华为云Java编程创造营][学习笔记][第三阶段][06_Java集合][02_Collection&Set]

举报
John2021 发表于 2021/12/19 14:17:23 2021/12/19
【摘要】 2,Java集合Collection接口及Set子类 2.1,Set接口和简介Set接口继承自Collection接口,但是并没有对方法进行扩充,是Collection的子接口。Set接口中元素无序,并且会对元素进行对比,保证存入的元素不出现重复。Set接口不允许重复元素,最多包含一个null。Set接口的遍历方式:使用迭代器或增强for循环。Set接口主要有两个实现类,分别是HashSe...

2,Java集合Collection接口及Set子类

2.1,Set接口和简介

  • Set接口继承自Collection接口,但是并没有对方法进行扩充,是Collection的子接口。
  • Set接口中元素无序,并且会对元素进行对比,保证存入的元素不出现重复。
  • Set接口不允许重复元素,最多包含一个null。
  • Set接口的遍历方式:使用迭代器或增强for循环。
  • Set接口主要有两个实现类,分别是HashSet和TreeSet。

2.2,HashSet子类和API

  • HashSet是Set接口的一个实现类,它不保证Set的迭代顺序,无需存放。
  • Set接口的唯一性:底层依赖于hashCode()和equals()方法。
import java.util.HashSet;

public class Test
{
    public static void main(String[] args)
    {
        HashSet<String> hashSet = new HashSet<>();

        hashSet.add("AB");
        hashSet.add("CD");
        hashSet.add("EF");
        hashSet.add("GH");
        hashSet.add("IJ");

        System.out.println(hashSet.size());//5

        for (String s : hashSet)
        {
            System.out.print(s + " , ");//AB , CD , EF , GH , IJ , 
        }
    }
}

2.3,TreeSet子类和API

  • TreeSet是Set接口的一个实现类,主要作用是对象的排序及确定存入对象的唯一性。
  • TreeSet中的元素支持2种排序方式:
    • 第一种:自然排序,在元素中定义排序规则。元素自身具有比较性,实现Comparable接口,重写compareTo方法。
    • 第二种:比较器排序,创建TreeSet时提供Comparator进行排序。实现Comparable接口,实现compare方法。
import java.util.Set;
import java.util.TreeSet;

public class Test
{
    public static void main(String[] args)
    {
        Set<String> allSet = new TreeSet<>();
        allSet.add("A");
        allSet.add("A");
        allSet.add("B");
        allSet.add("C");
        allSet.add("C");
        allSet.add("D");
        System.out.println(allSet);//[A, B, C, D]
    }
}

2.4,Set过滤重复和排序

  • Set集合存储元素的过程

  • Set过滤重复,重写hashCode()和equals()方法:

import java.util.HashSet;

class Stu
{
    private String stunum;
    private String name;

    @Override
    public int hashCode()
    {
        return this.name.hashCode() + this.stunum.hashCode();
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
        {
            return true;
        }
        else if (obj instanceof Stu)
        {
            Stu s = (Stu) obj;
            return (this.name + this.stunum).equals(s.name + s.stunum);
        }
        return false;
    }

    public String getStunum()
    {
        return stunum;
    }

    public void setStunum(String stunum)
    {
        this.stunum = stunum;
    }

    public String getName()
    {
        return name;
    }

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

    public Stu(String name, String stunum)
    {
        this.stunum = stunum;
        this.name = name;
    }
}

public class Test
{
    public static void main(String[] args)
    {
        Stu s1 = new Stu("小张", "10010060");
        Stu s2 = new Stu("小张", "10010060");

        HashSet<Stu> hashSet = new HashSet<>();
        hashSet.add(s1);
        hashSet.add(s2);

        System.out.println(hashSet.size());
        for (Stu s : hashSet)
        {
            System.out.println(s.getName() + "," + s.getStunum());
        }
    }
    /*
    * 输出结果
    *   1
        小张,10010060
    * */
}
  • TreeSet存储自定义对象并保证排序和唯一,实现Comparable接口,重写compareTo方法:
import java.util.TreeSet;

/*
 * 如果一个类的元素要想能够进行自然排序,就必须实现自然排序接口
 * */
class Student implements Comparable<Student>
{
    private String name;
    private int age;

    public Student()
    {
        super();
    }

    public Student(String name, int age)
    {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Student student)
    {
        //这里返回什么,其实应该根据定义的排序规则来做
        //按照年龄排序,主要条件
        int num = this.age - student.age;
        //次要条件
        //年龄相同的时候,还得去看姓名是否相同
        //如果年龄和姓名都相同,才是同一个元素
        int num2 = num == 0 ? this.name.compareTo(student.name) : num;
        return num2;
    }

    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;
    }

}

public class Test
{
    public static void main(String[] args)
    {
        //创建集合对象
        TreeSet<Student> ts = new TreeSet<>();
        //创建元素
        Student s1 = new Student("a", 12);
        Student s2 = new Student("b", 13);
        Student s3 = new Student("c", 14);
        Student s4 = new Student("d", 15);
        Student s5 = new Student("e", 16);
        //添加元素
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        //遍历
        for (Student s : ts)
        {
            System.out.println(s.getName() + "," + s.getAge());
        }
    }
    /*
    * 输出结果
    *   a,12
        b,13
        c,14
        d,15
        e,16
    * */
}

2.5,Set和List接口和子类的异同

  • List集合中的元素可重复,Set集合中的元素不可重复。
  • List集合中的元素是有序的,Set集合中的元素是无序的。
  • List中最常用的两个子类:ArrayList和LinkedList。
  • Set中最常用的两个子类:HashSet和TreeSet。
  • List中提供索引的方式来添加元素和获取元素,Set只能一个一个的比较,显然效率和实用性比不上List集合的。

2.6,迭代输出

  • Iterator迭代输出:
  • Iterable接口迭代遍历,优先选择Iterator接口,遍历Collection里所有的元素,也称为迭代器和迭代精灵;迭代是取出集合中元素的一种推荐方式。
import java.util.LinkedList;

public class Test
{
    static void execFor(LinkedList linkedList)
    {
        for (int i = 0; i < 50000; i++)
        {
            linkedList.add(i);
        }
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < linkedList.size(); i++)
        {
            linkedList.get(i);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("for循环遍历时间为:" + (endTime - startTime));
    }

    public static void main(String[] args)
    {
        execFor(new LinkedList());//for循环遍历时间为:975
    }
}
import java.util.Iterator;
import java.util.LinkedList;

public class Test1
{
    static void execIterator(LinkedList linkedList)
    {
        for (int i = 0; i < 50000; i++)
        {
            linkedList.add(i);
        }
        long startTime = System.currentTimeMillis();
        Iterator iterator = linkedList.iterator();
        while (iterator.hasNext())
        {
            iterator.next();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("Iterator循环遍历时间为:" + (endTime - startTime));
    }

    public static void main(String[] args)
    {
        execIterator(new LinkedList());//Iterator循环遍历时间为:4
    }
}

2.7,双向迭代输出

  • 双向迭代接口ListIterator,定义的方法:
    • hasPrevious() 判断是否有上一个元素
    • previous() 取得上一个元素
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class Test
{
    public static void main(String[] args)
    {
        List<String> all = new ArrayList<>();

        all.add("hello");
        all.add("_");
        all.add("java");

        ListIterator<String> listIterator = all.listIterator();
        while (listIterator.hasNext())
        {
            System.out.print(listIterator.next());
        }
        System.out.println("\n");
        while (listIterator.hasPrevious())
        {
            System.out.print(listIterator.previous());
        }
    }
    /*
    * 输出结果
    *   hello_java

        java_hello
    * */
}

2.8,枚举输出

  • 枚举输出Enumeration,JDK1.0时就引入了Enumeration接口,在JDK1.5时加入了泛型的应用。
  • 使用Enumeration接口的实例化对象,只能够依靠Vector子类,因为Enumeration设计就是为Vector服务的。
  • Enumeration定义的方法:
    • hasMoreElements():判断是否有下一个元素
    • nextElement():取得元素
import java.util.Enumeration;
import java.util.Vector;

public class Test
{
    public static void main(String[] args)
    {
        Vector<String> lists = new Vector<>();

        lists.add("A");
        lists.add("B");
        lists.add("C");
        lists.add("D");

        Enumeration<String> enumeration = lists.elements();
        while (enumeration.hasMoreElements())
        {
            System.out.println(enumeration.nextElement());
        }
    }
    /*
    * 输出结果
    *   A
        B
        C
        D
    * */
}

2.9,增强型for循环输出

  • 增强for循环是JDK1.5出现的新特征,底层使用的也是迭代器,使用for循环的格式,简化了迭代器的书写。
import java.util.ArrayList;

public class Test
{
    //增强for循环遍历集合
    private static void demo02()
    {
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        for (String str : list)
        {
            System.out.println(str);
        }
    }

    //增强for循环遍历集合
    private static void demo01()
    {
        int[] arr = {1, 2, 3, 4};
        for (int i : arr)
        {
            System.out.println(i);
        }
    }

    public static void main(String[] args)
    {
        demo01();
        System.out.println("================");
        demo02();
    }
    /*
    * 输出结果
    *   1
        2
        3
        4
        ================
        a
        b
        c
        d
    * */
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。