IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java集合框架系统学习3--Collection的所有方法简介 -> 正文阅读

[Java知识库]Java集合框架系统学习3--Collection的所有方法简介

前言:本章将对Collection接口里面定义的所有方法进行一个详解。
1、

int size();

这个很简单,就是返回当前集合中存了几个元素

2、

boolean isEmpty();

返回集合中是否是空,也就是说有元素就返回false,没元素就返回true

3、

boolean contains(Object o);

查看集合中是否存在o这个元素。注意,contains中是依赖对象的equals方法来判断两个对象是否相等的。所以如果说我把一个类型的equals方法重写了,让它一直返回false,那么这个类型的集合中调用contains方法是无法找到的,也就是永远返回true。我们可以看下面代码:

public class Client
{
    public static void main(String[] args)
    {
        test1();
    }
    private static void test1()
    {
        Collection<Student> stus= new ArrayList<Student>();
        stus.add(new Student("yqs",3303));
        stus.add(new Student("yqs",3304));
        stus.add(new Student("dsb",3300));
        System.out.println("是否存在:"+stus.contains(new Student("yqs",3309)));
        System.out.println("是否存在:"+stus.contains(new Student("yqs",3304)));
    }
    private static class Student
    {
        String name;//姓名
        int id;//身份证号码

        @Override
        public boolean equals(Object stu) {
            return id==((Student)stu).id;
        }

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

程序运行结果:

是否存在:false
是否存在:true

4、

Iterator<E> iterator();

这个方法返回一个迭代器对象,迭代器对象主要用来遍历集合里的元素。迭代器对象里面有一个next()方法,返回下一个元素(一开始指向第0个元素,也就是不存在的元素),所以我们第一次调用next()就会返回第一个元素,也就是"abc",第二次调用就会返回"qwer",以此类推,我们就可以利用这个迭代器对象遍历集合里面的元素了。下面放出迭代器对象的经典用法:

Collection<String> c= new ArrayList<String>();
c.add("abc");
c.add("qwer");
c.add("az");
Iterator<String> it=c.iterator();
while (it.hasNext())
{
   System.out.println(it.next());
}

这样子就可以遍历了

5、

Object[] toArray();

这个函数是将集合里面的元素转成一个数组然后返回。用法如下:

public static void main(String[] args)
{
	Collection<String> c= new ArrayList<String>();
	c.add("abc");
	c.add("qwer");
	c.add("az");
	Object[] arr= c.toArray();
	for (Object s: arr)
	{
	    System.out.println((String)s);
	}
}

输出如下:

abc
qwer
az

这里有一个问题,既然我们知道元素是String类型的,那为什么不直接这样:

String[] arr= (String[])c.toArray();

原因是,我们人知道这个数组里面寸的都是字符串,但是编译器并不知道这件事情。那有人说

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

我们定义的时候不是用泛型指定了数据类型了吗。但是我们仔细观察,发现我们的类型转化代码是写在main方法里面的,而不是集合内部,集合虽然知道我们的元素是String类型的,但是我们在main方法里的时候依然是不知道的。如果强行运行

String[] arr= (String[])c.toArray();

编译器会报这个错误:
class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.String; ([Ljava.lang.Object; and [Ljava.lang.String; are in module java.base of loader ‘bootstrap’)

我们知道,我们平时写代码是可以这样子类型转化的:

Object obj="123";
String str=(String)obj;

很显然上面代码是合法的,jvm也不会阻止你这样做(当然如果你的类型转化不合理jvm也会给你报一个运行时错误的)。
Object可以转String,那为什么到了Object[]数组就不行了呢?这里我给出一下自己的理解,如有问题,可以指正。就比如如果我的Object数组是这么定义的:

Object[] objects=new Object[]{"123",new Student(),52,'8',new Cat()};

懂了吧,Object数组里面又不是只会存一种数据类型,但是你转化的时候只能往一个类型去转,所以这样子转的不确定性和不稳定性很大,显然是不合理的,所以jvm干脆就不然你转了。有小伙伴会问,集合内部的Object数组肯定是存的同一种类型呀。但是你要明白,Object数组又不是只给你集合类用的,它在很多其它地方也有使用,所以jvm必须要考虑所有的情况。

6、

<T> T[] toArray(T[] a);

这个方法就是为了解决上面第5个方法的不足,我们可以在调用toArray的时候传入一个数组类型来显式的指定我们要什么类型的数据,这样子toArray内部就可以拿着这个类型,对元素一一进行的类型转化,最后返回数组。
所以说a这个参数就是用来指明我想要的类型。
如果a这个数组的长度大于等于元素的个数,那么方法内部会直接把元素添加到这个a上面,然后返回的那个数组就是传入的这个a数组。
如果小于的话,方法内部就会新建一个长度刚好的数组,然后存元素,然后返回。

7、

default <T> T[] toArray(IntFunction<T[]> generator) 
{
	return toArray(generator.apply(0));
}

这个的话稍微复杂一点,可能需要一点基础才能明白。
我们先看下
IntFunction这个接口的定义:

@FunctionalInterface
public interface IntFunction<R> {

	/**
	* Applies this function to the given argument.
	*
	* @param value the function argument
	* @return the function result
	*/
	R apply(int value);
}

其实接口很简单,就一个函数,也就是一个函数式接口,可以用来表示一个函数(具体可以百度函数式接口)。
我们向toArray方法传入一个函数,然后toArray方法内部会调用一次这个函数,传入的参数是0,个人理解这里传0还是传什么不重要,因为想要调用这个方法肯定是要传一个参数的。最后把这个函数的返回值传给我们上面第6个介绍的那个toArray中去,最后把返回值返回。具体怎么用呢,这里给出我个人的一个理解:

Collection<String> c= new ArrayList<String>();
c.add("abc");
c.add("qwer");
c.add("az");
String[] strings=c.toArray(new IntFunction<String[]>() {
    @Override
    public String[] apply(int value)
    {
        System.out.println("传入的value参数是:"+value);
        return new String[c.size()];
    }
});
for(String s:strings)
{
    System.out.println(s);
}

输出是:

传入的value参数是:0
abc
qwer
az

或者可以直接这样:

Collection<String> c= new ArrayList<String>();
c.add("abc");
c.add("qwer");
c.add("az");
String[] strings=c.toArray(String[]::new);
for(String s:strings)
{
    System.out.println(s);
}

输出是:

abc
qwer
az

这一块需要函数式接口的知识,大家可以自行学习。
那么这个方法和第6个那个方法有啥区别呢,个人理解是可能用起来会更放别简洁一点。

8、

boolean add(E e);

这个的话就很熟悉了,用来添加一个元素到集合中去,并且返回一个布尔值表示是否添加成功。前面的很多代码块都大量的用到了这个add方法,大家可以翻上去看看。

9、

boolean remove(Object o);

这个和add是对立的,add用来添加,这个用来删除。具体是删除集合中第一个和o相等的元素,如何判断是否相等呢,这里和上面的那个contains方法一致,都是依赖equals方法来判断的。下面给出一段测试代码:

public static void main(String[] args)
{
    Collection<Student> c= new ArrayList<Student>();
    c.add(new Student("yqs",3303));
    c.add(new Student("yqs1",3304));
    c.add(new Student("yqs2",3304));
    c.add(new Student("yqs",3305));
    c.remove(new Student("yqs",3304));
    for (Student stu:c)
    {
        System.out.println(stu.name+" "+stu.id);
    }
}
class Student
{
    String name;//姓名
    int id;//身份证号码

    @Override
    public boolean equals(Object stu) {
        return id==((Student)stu).id;
    }

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

执行结果是:

yqs 3303
yqs2 3304
yqs 3305

大家可以对着代码自行理解,应该不难。

10、

boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean removeAll(Collection<?> c);

这几个其实都差不多,前面的是添加删除查找单个元素,这里的话就变成添加查找删除一个元素集。因为都差不多,所以直接写到一段代码里面去:

public static void main(String[] args)
{
    Collection<Student> class1= Stream.of(
            new Student("yqs1",11),new Student("yqs2",12),new Student("yqs3",13))
            .collect(Collectors.toList());//1班的同学
    Collection<Student> class2= Stream.of(
            new Student("bbq1",21),new Student("bbq2",22),new Student("bbq3",23))
            .collect(Collectors.toList());//2班的同学
    Collection<Student> allStus= new ArrayList<Student>();//所有的同学
    allStus.addAll(class1);
    allStus.addAll(class2);
    System.out.println("所有学生名单:");
    for(Student stu:allStus)
    {
        System.out.println(stu.name+" "+stu.id);
    }
    Collection<Student> tempClass= Stream.of(
            new Student("yqs1",11),new Student("bbq1",21),new Student("llc",99))
            .collect(Collectors.toList());//临时班级同学,里面含有不在学生名单里的学生
    System.out.println("所有学生里是否有所有临时班级的学生:"+allStus.containsAll(tempClass));
    System.out.println("所有学生里是否有所有1班的学生:"+allStus.containsAll(class1));
    allStus.removeAll(tempClass);
    System.out.println("把临时班级和所有学生里共同存在的学生从所有学生中删除");
    System.out.println("删除后的名单是:");
    for(Student stu:allStus)
    {
        System.out.println(stu.name+" "+stu.id);
    }
}

输出结果是:

所有学生名单:
yqs1 11
yqs2 12
yqs3 13
bbq1 21
bbq2 22
bbq3 23
所有学生里是否有所有临时班级的学生:false
所有学生里是否有所有1班的学生:true
把临时班级和所有学生里共同存在的学生从所有学生中删除
删除后的名单是:
yqs2 12
yqs3 13
bbq2 22
bbq3 23

这里我用了Stream.of来构建集合,因为这样子比一个个add要方便。感兴趣的小伙伴可以学习一下java的Stream操作。
一句话总结:
addAll就是集合的并集操作,removeAll就是集合的作差,containsAll就是判断两个集合的交集是否属于第一个集合。

11、

default boolean removeIf(Predicate<? super E> filter)

也是函数式接口的内容,我们需要传入一个过滤器函数,告诉集合我需要删除哪些特征的元素,话不多说,上代码,下面代码就是用来删除名字以y开头的学生:

public static void main(String[] args)
{
    Collection<Student> students= Stream.of(
            new Student("yqs",11),new Student("yhh",12),new Student("zzz",13),
            new Student("obj",14),new Student("yes",15),new Student("kbl",16))
            .collect(Collectors.toList());
    System.out.println("删除前:");
    for(Student stu:students)
    {
        System.out.println(stu.name+" "+stu.id);
    }
    students.removeIf(new Predicate<Student>() {
        @Override
        public boolean test(Student student) {
            return student.name.charAt(0)=='y';
        }
    });
    System.out.println("删除后:");
    for(Student stu:students)
    {
        System.out.println(stu.name+" "+stu.id);
    }
}

输出结果:

删除前:
yqs 11
yhh 12
zzz 13
obj 14
yes 15
kbl 16
删除后:
zzz 13
obj 14
kbl 16

未完待续。。。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-07 11:53:51  更:2021-12-07 11:55:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:29:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码