JAVA集合(一)Collection接口

集合的框架:

前面我们保存多个数据使用的是数组。数组有不足的地方 

数组的特点如下所示:

(1)长度开始时必须指定,而且一旦指定,不能更改

示例如下:

我们创建了一个数组:int [] n=new int[3]。   

声明数组的方式有以下两种:1。数据类型 [  ]数组名=null;  int [ ]n=null

2.数据类型[ ]数组名;

数组名=new 数据类型[长度 ];(int [] n;n=new int [10])

数组的静态初始化有两种方式,具体格式如下

类型 [ ]数组名 =new 类型[ ]{元素,....}

类型 [ ]数组名={元素,元素.......}

当我们对这个数组进行扩容的时候,我们需要创建一个新的数组,然后再把原数组拷贝过去很麻烦。

(2)保存的必须为同一类型的元素

(3)使用数组进行增加或者删除元素的示意代码--比较麻烦

示例如下所示:我们有一个Person数组,

Person[ ] pers=new Person[ 1];  //大小是1,对于这个数组增加一个新的person对象。

我们的做法如下:

(1)创建一个新的数组:

Person [ ] pers2=new Person[pers.length+1];  //新创建一个数组

(2)

for(){}   /拷贝pers数组的元素到pers2

(3)

pers2[pers2.length-1]=new Person();//添加新的对象

我们的示例代码如下所示:

package com.rgf.servlet.user;

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

        int[ ] pers={1,2,3,4,5}; //大小是1,对于这个数组增加一个新的person对象。
        int jihe=100;
        int [ ] pers2=new int[pers.length+1];
           for(int i=0;i<pers.length;i++){
               pers2[i]=pers[i];
        }
        pers2[pers2.length-1]=jihe;//添加新的对象
           for (int j = 0;j<pers2.length;j++){
            System.out.println(pers2[j]);

        }
    }
}

运行界面如下所示:

集合(多种数据放在一起):

(1)可以动态保存任意多个对象,使用比较方便

(2)提供了一系列方便的操作对象的方法:add、remove、set、get等

(3)使用集合添加、删除新元素的示意代码-简洁了

集合的框架体系:

java的集合类很多,主要分为两大类,如图:

Collection.java

package com.rgf.jihe;

/**
 * 一、集合框架的概述
 * 1.集合、数组都是对多个数据进行存储操作的结构,简称java容器。
 * 说明:此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储(.txt,.jpg,.avi,数据库中)
 * 2.1数组在存储多个数据方面的特点:
 *   >一旦初始化以后,其长度就确定了。
 *   >比如:数组一旦定义好,其元素的类型1也就确定了。我们也就只能操作指定类型的数据了。
 * Stirng[] arr,int [] arr1;Object [] arr2;
 *  2.2数组在存储多个数据方面的缺点:
 *   >一旦初始化以后,其长度就不可修改。
 *   >数组中提供的方法非常有限,对于添加、删除、插入数据等操作,非常不便,同时效率不高。
 *   >获取数组中实际元素的个数的需求,数组没有现成的属性或方法可用
 *   >数组存储数据的特点:有序、可重复。对于无序、不可重复的需求,不能满足。
 *二、集合框架
 *  1.Collection接口(单列集合,用来存储一个一个的对象)
 *  set(无序不可重复):hashset、treeset、Linkedhashset
 *  list(有序可重复,动态数组):linkedlist、Arraylist、Vector
 *  2.Map接口(双列集合,用来存储一对(key - value)一对的数据)
 *  hashMap、LinkedHashMap、Hashtable、properties
 *  treemap
 */
public class ConnectionTest {

}

 collection集合为单列集合。(单列集合即为在这个集合里面放的单个的对象)

其中,Linkedlist为链表的list,ArrayList为数组的list。

 Map集合为双列集合(双列集合放的是键值对形式的)

集合主要是两组:双列集合(Map集合)和单列集合(Collection集合)。

Collection接口有两个重要的子接口:Set(元素无序、不可重复的集合)和List(元素有序、可重复的集合),他们的实现子类都是单列集合。(里面放的单个单个的元素)

Map接口的实现子类:HashMap和TreeMap,HashTable。他们的实现子类为双列集合(里面放的为键值对,为key-value形式的值)

我们更加形象的查看双列集合和单列集合:

 //添加单列集合
        ArrayList arrayList = new ArrayList();
        arrayList.add("jdbc");
        arrayList.add("javaweb");
        HashMap hashMap = new HashMap();
        //添加双列集合
        hashMap.put("number1","北京");
        hashMap.put("number2","上海");

Collection接口:

Collection接口实现类的特点:

public interface Collection <E> extends Iterable<E>

(1)Collection实现子类可以存放多个元素,每个元素可以是Object

(2)有些Collection的实现类,可以存放重复的元素(List),有些不可以(Set)

(3)有些Collection的实现类,有些是有序的(List),有些不是有序(Set)

(4)Collection接口没有直接的实现子类,是通过它的子接口Set和List来实现的。

Collection接口的常用方法:

向Collection接口的实现类的对象中添加数据obj时,要求obj所在类要重写equals().

由于Collection接口本身不能被实例化的,我们以实现子类ArrayList来进行示例:

package com.rgf.collection;

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

public class CollectionMethod {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        List list = new ArrayList();
        //add:add(Object e):将元素e添加到集合coll中
        list.add("jdbc");
        list.add(10);//所添加的数已经不是基本数据类型,而是对象,本质是这么装的:list.add(new Integer(10))  自动装箱
        list.add(true);
        System.out.println("list="+list);
        //remove:删除指定元素
        //remove(Object o),删除的是一个对象,返回的就是一个boolean值,即为是否删除成功
        //remove(int index),删除的是一个索引值,返回的是被删除的对象。
        list.remove("jdbc");
        System.out.println("list="+list);
        list.remove(0);//删除第一个元素
        System.out.println("list="+list);
        //contains:查找元素是否存在(contains(Object obj):判断当前集合中是否包含obj,判断的是内容,而不是地址。String重写过了equals方法,是比较内容,如果没有重写equals方法,在调用equals的时候是调用Object里面的,里面为==。
       //我们在判断时会调用obj对象所在类的equals()。
        System.out.println(list.contains(true));//返回true
        System.out.println( list.contains("rgf"));//返回false
        //size:获取添加的元素的个数
        System.out.println(list.size());//1
        //isEmpty:判断当前集合是否为空
        System.out.println(list.isEmpty());
        //clear:清空
        list.clear();
        System.out.println("list"+list);
        //addAll:添加多个元素,addAll(Connection c),实现了Connection接口的类的一个对象都可以传进去
       List list2 = new ArrayList();
       list2.add("三国演义");
       list2.add("红楼梦");
        System.out.println("list2="+list2);
        list.addAll(list2);
        System.out.println("list="+list);
        //containsAll:查找多个元素是否都存在
        System.out.println(list.containsAll(list2));  //true
        //removeAll:删除多个元素.以下代码为把list里面中的所有list2中的元素全部删掉,即把他们的交集删掉。
        list.add("水浒传");
        list.removeAll(list2);
        System.out.println("list="+list);



    }
}

我们运行之后,如下所示:

方法示例二:

package com.rgf.jihe;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * 一、集合框架的概述
 * 1.集合、数组都是对多个数据进行存储操作的结构,简称java容器。
 * 说明:此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储(.txt,.jpg,.avi,数据库中)
 * 2.1数组在存储多个数据方面的特点:
 *   >一旦初始化以后,其长度就确定了。
 *   >比如:数组一旦定义好,其元素的类型1也就确定了。我们也就只能操作指定类型的数据了。
 * Stirng[] arr,int [] arr1;Object [] arr2;
 *  2.2数组在存储多个数据方面的缺点:
 *   >一旦初始化以后,其长度就不可修改。
 *   >数组中提供的方法非常有限,对于添加、删除、插入数据等操作,非常不便,同时效率不高。
 *   >获取数组中实际元素的个数的需求,数组没有现成的属性或方法可用
 *   >数组存储数据的特点:有序、可重复。对于无序、不可重复的需求,不能满足。
 *二、集合框架
 *  1.Collection接口(单列集合,用来存储一个一个的对象)
 *  set(无序不可重复):hashset、treeset、Linkedhashset
 *  list(有序可重复,动态数组):linkedlist、Arraylist、Vector
 *  2.Map接口(双列集合,用来存储一对(key - value)一对的数据)
 *  hashMap、LinkedHashMap、Hashtable、properties
 *  treemap
 */
public class ConnectionTest {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(123);
        list.add(456);
        list.add(new Person("Jerry",20));
        ArrayList list1 = new ArrayList();
        list1.add(123);
        list1.add(456);
        list1.add(new Person("Jerry",20));

        //retainAll(Collection coll1):获取当前集合和list1集合的交集,并返回给当前集合
        list.retainAll(list1);
        System.out.println(list);  //[123,

        //equals(Object obj):要想返回true,需要当前集合和形参集合的元素都相同。
        // 如果顺序不一致,也不一样,实现类ArrayList是有序的
        System.out.println(list.equals(list1));

        //hashCode():返回当前对象的哈希值
        System.out.println(list.hashCode());

        //集合 --->数组:toArray()
        Object[] objects = list.toArray();
        for (int i=0;i< objects.length;i++){
            System.out.println(objects[i]);
        }


        //数组--->集合:调用Arrays类的静态方法aList()
        List<String> LIST = Arrays.asList(new String[]{"AA", "BB", "CC"});
        System.out.println(LIST);

        List<int[]> ints = Arrays.asList(new int[]{123, 456});
        System.out.println(ints);
        System.out.println(ints.size()); //1

        List ints1 = Arrays.asList(new Integer(789),new Integer(441));
        System.out.println(ints1);
        System.out.println(ints1.size());

        //iterator():返回Iterator接口的实例,用于遍历集合元素。
    }

}
class  Person{
    String name;
    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 boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Person person = (Person) o;

        if (age != person.age) return false;
        return name != null ? name.equals(person.name) : person.name == null;
    }


}

 运行之后如下所示:

 Collection接口遍历元素方式1----使用Iterator(迭代器)

 我们可知:Collection的父接口为Iterable。

我们查看Iterator的源码如下所示:

 我们发现Iterable里面有个很重要的方法,即为Iterator方法。

可以通过Iterator方法返回一个Iterator对象。Iterator对象就是我们所说的迭代器对象。

我们可以使用Iterator对象进行所有元素的一个遍历。

只要是实现了Collection接口的子类,都可以去获取到一个Iterator(迭代器),然后用这个迭代器来遍历这个集合里面的所有对象。

(1)Iterator对象称为迭代器,主要用于遍历Collection集合中的元素

(2)所有实现了Collection接口的集合类都有一个Iterator()方法,用以返回一个实现了Iterator接口的对象,既可以返回一个迭代器。

(3)Iterator的结构:

迭代器的执行原理:

我们有一个竖表:

123
AA
new  Date()
2

这个表相当于数组一样,可以把数据都存放进里面去,当我们通过Iterator方法,得到一个迭代器后,我们每次调用这个迭代器的next方法,就会往下移动 一格,每调用一次,往下移动一次,并且把这个数据取出来,直到把最后一个数据取出来之后,再往下移动之后,取不到东西从而退出。

Iterator iterator =coll.iterator();//得到一个集合的迭代器

//hasNext():判断是否还有下一个元素,没有会返回false(Iterator对象的一个方法)

while(Iterator.hasNext()){   //返回false后,这个循环会结束

//next():1指针下移2.将下移以后集合位置上的元素返回

System.out.println(iterator.next());

}

我们进行查看源码:

Iterator接口里面有个hasNext方法,hasNext方法会如果iteration有更多的元素,会返回true。没有更多的元素则会返回false。 

其中的next()方法有两个作用://next():1指针下移2.将下移以后集合位置上的元素返回

Iterator接口的方法:

 注意:在调用Iterator.next()方法之前必须要调用Iterator.hasNext().

进行检测,若不调用,且下一条记录无效,直接调用Iterator.next()会抛出NoSuchElementException异常。

我们发现迭代器里面有一个remove.我们进行实现如下所示:

package com.rgf.jihe;

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

/**
 * 集合元素的遍历操作,使用迭代器Iterator接口
 * 1.内部的方法:hasNext()和next()
 * 2.集合对象每次调用iterator()方法都得到一个全新的迭代器对象
 * 默认游标都在集合的第一个元素之前
 * 3.内部定义了remove(),可以在遍历的时候,删除集合中的元素,此方法不同于集合直接调用remove()
 *
 */
public class Iterator2 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add("123");
        list.add("456");
        list.add(new String("沃尔"));
        //Iterator可以删除集合的元素,但是是遍历过程中通过迭代器对象的remove方法,不是集合对象的remove方法。
        //如果还未调用next()或在上一次调用next方法之后已经调用了remove方法,再调用remove都会报IllegalStateException
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            Object next = iterator.next();
            if("沃尔".equals(next)){
                iterator.remove();
        }
    }
        Iterator iterator1 = list.iterator();
        while (iterator1.hasNext()){
            System.out.println( iterator1.next());
        }
    }
}

 运行之后如下所示:

 (4)Iterator仅用于遍历集合,并不是容器,Iterator本身并不存放对象。

Iterator接口的实现:

package com.rgf.collection;

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

public class CollectionIterator {
    public static void main(String[] args) {
        List col = new ArrayList();
        col.add(new Book("三国演义","罗贯中",52.2));
        col.add(new Book("西游记","吴承恩",22.5));
        col.add(new Book("红楼梦","曹雪芹",32.8));
        System.out.println("col="+col);
        //我们进行输出的时候发现是连着输出,但是现在我们希望一个一个进行取出。如下所示:
        //先得到col对应的迭代器
        Iterator iterator = col.iterator();
       //此时返回iterator对象的时候,此时的指针是指在第一个对象的上面。当调用hasNext的时候,判定为true的时候,执行next,此时返回第一个数的同时,指针进行下移。之后再次调用next.
        //使用while循环遍历,我们可以使用快捷键进行快速循环:itit,
        // 显示所有的快捷键的快捷键:ctrl+j,我们可以查看当前的快捷模板。
        while(iterator.hasNext()){ //hasNext:判断集合中是否还有下一个元素
            //返回下一个元素,类型是object。
            Object object = iterator.next();//取出集合中的对象
            //编译类型为object,但是我们的运行类型是取决于我们真正存放的类型。
            System.out.println("object="+object);
        }
        //当迭代器退出while循环后,这是iterator指向了最后的元素。
     //   iterator.next(); //NoSuchElementException
     //如果希望再次遍历,需要重置我们的迭代器。
iterator=col.iterator();
        System.out.println("===第二次遍历===");
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println("next="+next);

        }
    }
}
class Book{
    private String name;
    private String author;
    private  double price;

    public Book(String name, String author, double price) {
        this.name = name;
        this.author = author;
        this.price = price;
    }

    public String getName() {
        return name;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                '}';
    }
}

运行界面如下所示:

错误使用迭代器的两种方式如下所示:

package com.rgf.jihe;

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

public class Iterator1 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(123);
        list.add(456);
        
        //错误方式一:会报错,同时会间隔输出
        Iterator iterator = list.iterator();
        while (iterator.next()!=null){
            System.out.println(iterator.next());
        }
        
        //错误方式二:每当调用list.iterator方法,都会返回一个迭代器对象,这个迭代器的对象是新的,新的就会在数据的开头。就会一直在第一个位置
        while (list.iterator().hasNext()){
            System.out.println(list.iterator().next());
        }
    }
}

 Collection接口遍历元素方式2----增强for循环

增强for循环,可以代替iterator迭代器,特点:增强for循环就是简化版的iterator,本质一样。只能用于遍历集合或数组。

基本语法:

for(元素类型  元素名:集合名或数组名){

访问元素

}

我们的代码示例如下所示:

package com.rgf.collection;

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

public class CollectionIterator {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        List col = new ArrayList();
        col.add(new Book("三国演义", "罗贯中", 52.2));
        col.add(new Book("西游记", "吴承恩", 22.5));
        col.add(new Book("红楼梦", "曹雪芹", 32.8));
        //使用增强for循环
        //for(元素类型 元素名称: 集合名或元素名)
        for(Object book:col){
            System.out.println("book="+book);
        }
        //1.增强for可以直接在数组上使用,也可以在Collection集合使用。
        //2.增强for,它的底层仍然是迭代器
        //3.可以理解成增强for循环就是简化版本的迭代器遍历
        //4.快捷键方式:I
        int [] arr={1,8,10,90};
        for(int i:arr){
            System.out.println("i="+i);
        }
    }
}
class Book{
    private String name;
    private String author;
    private  double price;

    public Book(String name, String author, double price) {
        this.name = name;
        this.author = author;
        this.price = price;
    }

    public String getName() {
        return name;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                '}';
    }
}

运行之后如下所示:

增强for循环的底层仍然是迭代器,我们可以通过断点的方式进行查看:

 

我们点击Debug进行查看:

我们发现进入如下界面。


 

 我们发现进入的页面也是调用了Iterator,调用了hasNext的方法和next的方法。

增强for循环内部仍然使用的是迭代器Iterator。

我们进行如下练习:

package com.rgf.jihe;

public class IteratorE {
    public static void main(String[] args) {
      String[] arr=new String[]{"MM", "MM", "MM"};
      //方式一:普通for赋值,这种方式可以将值进行修改
      for (int i=0;i<arr.length;i++){
          arr[i]="GG";
        }
        for (String i:arr){
            System.out.println(i);
        }

        String[] arr1=new String[]{"MM", "MM", "MM"};
      //方式二:增强for循环,此时我们输出仍然为MM,因为在增强for循环中,我们相当于把arr里面的数据先取出来,然后赋值给s,我们修改的是s,
        //而不是arr。所以仍然为MM.
        for(String s:arr1){
            s="GG";
        }

      for (String i:arr1){
          System.out.println(i);
      }

    }
}

我们运行之后如下所示:

 

 小测试:

编写程序CollectionExercise.java

1.创建3个Dog(name,age)对象,放入到ArrayList中,赋给List引用

2.用迭代器和增强for循环两种方式来遍历

3.重写Dog的toString方法,输出name和age。

我们首先创建:

package com.rgf.collection;

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

之后编写Dog类。

package com.rgf.collection;

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

    }
}
class Dog{
    private String name;
    private int age;
    
}

设置他们的构造器和getter和setter方法和toString方法:

package com.rgf.collection;

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

    }
}
class Dog{
    private String name;
    private int age;

    public Dog(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 "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

之后我们进行创建集合,进行遍历输出:

package com.rgf.collection;

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

public class CollectionExercise {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(new Dog("小黑",10));
        list.add(new Dog("大黄",15));
        list.add(new Dog("jack",5));
       //先使用增强for循环。
        for (Object dog :list) {
            System.out.println("dog="+dog);
        }
      //使用iterator迭代器
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            Object dog =  iterator.next();
            System.out.println("dog="+dog);
        }

    }
}
class Dog{
    private String name;
    private int age;

    public Dog(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 "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

运行之后如下所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直再追梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值