javaEE 集合概述

集合与数组的区别,缓存管理,Collection、List、Set接口

1.Colloction接口

java类中保存单值的最大操作父接口,里面每次操作的时候都只能保存一个对象的数据。

public interface Collection extends Iterable
常用方法:
1.public boolean add(E e) 集合中插入一个元素
2.public boolean addAll(Collection<? extends E> c) 向集合中插入一组元素
3. public void clear() 清空集合中的元素
4.public boolean contains(Object o) 查找一个元素是否存在
5 public boolean containsAll(Collection<?> c) 查找一组元素是否存在
6 public boolean isEmpty() 判断集合是否为空
7 public Iterator **iterator() ** 为 Iterator 接口实例化
8 public boolean remove(Object o) 从集合中删除一个对象
9 boolean removeAll(Collection<?> c) 从集合中删除一组对象
10 boolean retainAll(Collection<?> c) 判断是否没有指定的集合
11 public int size() 求出集合中元素的个数
12 public Object[] toArray() 以对象数组的形式返回集合中的全部内容
13 T[] toArray(T[] a) 指定操作的泛型类型,并把内容返回
14 public boolean equals(Object o) 普通 从 Object 类中覆写而来
15 public int hashCode() 从 Object 类中覆写而来

在开发中不会直接使用 Collection 接口。而使用其操作的子接口:List、Set

2.、List 接口(重点)

在整个集合中 List 是 Collection 的子接口,里面的所有内容都是允许重复的。
List子接口定义
public interface List extends Collection
1 public void add(int index,E element) 在指定位置处增加元素
2 boolean addAll(int index,Collection<? extends E> c) 在指定位置处增加一组元素
3 public E get(int index) 根据索引位置取出每一个元素
4 public int indexOf(Object o) 根据对象查找指定的位置,找不到返回-1
5 public int lastIndexOf(Object o) 从后面向前查找位置,找不到返回-1
6 public ListIterator listIterator() 返回 ListIterator 接口的实例
7 public ListIterator listIterator(int index) 返回从指定位置的 ListIterator 接口的实例
8 public E remove(int index) 删除指定位置的内容
9 public E set(int index,E element) 修改指定位置的内容
10 List subList(int fromIndex,int toIndex) 返回子集合

常用的实现类有如下几个:
ArrayList(95%)、Vector(4%)、LinkedList(1%)

3.ArrayList(重点)

ArrayList 是 List 接口的子类,此类的定义如下:
public class ArrayList extends AbstractList
implements List, RandomAccess, Cloneable, Serializable

此类继承了 AbstractList 类。AbstractList 是 List 接口的子类。AbstractList 是个抽象类,适配器设计模式。
此时的对象数组并没有长度的限制,长度可以任意长,只要是内存够大就行。
使用 remove()方法删除若干个元素,并且使用循环的方式输出。 ·
根据指定位置取的内容的方法,只有 List 接口才有定义,其他的任何接口都没有任何的定义。

import java.util.ArrayList; 
import java.util.List; 
public class ArrayListDemo02 { 
public static void main(String[] args) { 
    List<String> all = new ArrayList<String>(); // 实例化List对象,并指定泛型类型 
        all.add("hello "); // 增加内容,此方法从Collection接口继承而来 
        all.add(0, "LAMP ");// 增加内容,此方法是List接口单独定义的 
        all.add("world"); // 增加内容,此方法从Collection接口继承而来 
        all.remove(1); // 根据索引删除内容,此方法是List接口单独定义的 
        all.remove("world");// 删除指定的对象 System.out.print("集合中的内容是:"); 
        for (int x = 0; x < all.size(); x++) { // size()方法从Collection接口继承而来 
            System.out.print(all.get(x) + "、"); // 此方法是List接口单独定义的 
        } 
    } 
}

4.Vector

与 ArrayList 一样,Vector 本身也属于 List 接口的子类,此类的定义如下:
public class Vector extends AbstractList
implements List, RandomAccess, Cloneable, Serializable

·与使用 ArrayList 本身并没有任何的区别。因为操作的时候是以接口为操作的标准
Vector 类和 ArrayList 类的区别(重点)
在这里插入图片描述

5.LinkedList

此类继承了 AbstractList,所以是 List 的子类。但是此类也是 Queue 接口的子类,Queue 接口定义了如下的方法:
1 public boolean add(E e) 增加元素,如果有容量限制,并且已满,则抛出异 常
2 public E element() 取得,但是不删除当前元素,如果对列为空则抛出 异常
3 boolean offer(E e) 添加,如果有容量限制,并且已满,只是无法添加, 但不抛出异常,返回 false
4 E peek() 取得头元素,但是不删除,如果队列为空,则返回 null
5 E poll() 取得头元素,但是删除, 如果队列为空,则返回 null
6 E remove() 删除当前元素, 如果对列为空则抛出异常

public static void main(String[] args) { 
    Queue queue = new LinkedList(); 
    queue.add("A"); queue.add("B"); 
    queue.add("C"); int len=queue.size();
    //把queue的大小先取出来,否则每循环一次,移除一个元素,就少 一个元素,
    //那么queue.size()在变小,就不能循环queue.size()次了。 
    for (int x = 0; x<len; x++) { 
        System.out.println(queue.poll()); 
    } 
    System.out.println(queue);
}

6.Set接口

Set 接口也是 Collection 的子接口,与 List 接口最大的不同在于,Set 接口里面的内容是不允许重复的。
Set 接口并没有对 Collection 接口进行扩充,基本上还是与 Collection 接口保持一致。
因为此接口没有 List 接口中定义 的 get(int index)方法,所以无法使用循环进行输出。
那么在此接口中有两个常用的子类:HashSet、TreeSet

7.HashSet

既然 Set 接口并没有扩充任何的 Collection 接口中的内容,所以使用的方法全部都是 Collection 接口定义而来的。

public static void main(String[] args) { 
Set all = new HashSet(); // 实例化Set接口对象 
    all.add("A"); all.add("B"); 
    all.add("C"); all.add("D"); 
    all.add("E"); 
    System.out.println(all);
 }

使用 HashSet 实例化的 Set 接口实例,本身属于无序的存放。
因为在 Collection 接口中定义了将集合变为对象数组进行输出,可以通过循环的方式将 Set 接口中的内容输出

public static void main(String[] args) { 
Set all = new HashSet(); // 实例化Set接口对象 all.add("A"); 
    all.add("B"); 
    all.add("C"); 
    all.add("D"); 
    all.add("E"); 
    Object obj[] = all.toArray(); // 将集合变为对象数组 
    for (int x = 0; x < obj.length; x++) { 
        System.out.print(obj[x] + "、"); 
    } 
}

但是,以上的操作不好,因为在操作的时候已经指定了操作的泛型类型,那么现在最好的做法是由泛型所指定的类 型变为指定的数组。 所以只能使用以下的方法T[]
toArray(T[] a)


String[] str = all.toArray(new String[] {});// 变为指定的泛型类型数组 
for (int x = 0; x < str.length; x++) 
{ 
    System.out.print(str[x] + "、"); 
}

8.排序的子类:TreeSet(重点)

与 HashSet 不同的是,TreeSet 本身属于排序的子类
public class TreeSet extends AbstractSet
implements NavigableSet, Cloneable, Serializable

public static void main(String[] args) { 
Set all = new TreeSet(); // 实例化Set接口对象\ 
    all.add("D"); 
    all.add("X"); 
    all.add("A"); 
System.out.println(all);
 }

虽然在增加元素的时候属于无序的操作,但是增加之后却可以为用户进行排序功能的实现。
排序说明
个人理解:TreeSet在调用add之前 对象会实现Comparable接口中的compareTo()方法返回正负或0,0表示重复元素,正负来决定插入的位置(左右节点)

public class Person implements Comparable { 
private String name; private int age; 
public int compareTo(Person per) { 
    if (this.age > per.age) {
         return 1;
     } else if (this.age < per.age) { 
        return -1; 
    } else { 
        return 0; 
    } 
}

小结:
1.TreeSet 集合中的对象的类型必须实现了 Comparable 接口。
关于 TreeSet 的排序实现,如果是集合中对象是自定义的或者说其他系统定义的类没有实现
Comparable 接口,则不能实现 TreeSet 的排序,会报类型转换(转向 Comparable 接口)错误。
换句话说要添加到 TreeSet 集合中的对象的类型必须实现了 Comparable 接口。
2.HashSet不能去掉重复值的
不过 TreeSet 的集合因为借用了 Comparable 接口,同时可以去除重复值,而 HashSet 虽然是 Set 接口子类,但是对于没有复写 Object 的 equals 和 hashCode 方法的对象,加入了 HashSet 集合中也是不能去掉重复值的。

9.集和输出

已经学习过了基本的集合操作,那么对于集合的输出本身也是有多种形式的,可以使用如下的几种方式:
· Iterator 迭代输出(90%)、ListIterator(5%)、Enumeration(1%)、foreach(4%)
但是在讲解输出的时候一定要记住以下的原则:“只要是碰到了集合,则输出的时候想都不想就使用 Iterator 进行输出。

9.1 Iterator

Iterator 属于迭代输出,基本的操作原理:是不断的判断是否有下一个元素,有的话,则直接输出。
要想使用此接口,则必须使用 Collection 接口,在 Collection 接口中规定了一个 iterator()方法,可以用于为 Iterator接口进行实例化操作。
此接口规定了以下的三个方法:
1 boolean hasNext() 是否有下一个元素
2 E next() 取出内容
3 void remove() 删除当前内容
terator 中的操作指针是在第一条元素之上,当调用 next()方 法的时候,获取当前指针指向的值并向下移动,使用 hasNext()可以检查序列中是否还有元素。

在这里插入图片描述

public static void main(String[] args) { 
Collection all = new ArrayList(); all.add("A"); 
    all.add("B"); 
    all.add("C"); 
    all.add("D"); 
    all.add("E"); 
    Iterator iter = all.iterator(); 
    while (iter.hasNext()) {// 判断是否有下一个元素 
        String str = iter.next(); // 取出当前元素 
        System.out.print(str + "、"); 
    } 
}

但是在使用 Iterator 输出的时候有一点必须注意,在进行迭代输出的时候如果要想删除当前元素,则只能使用 Iterator 接口中的 remove()方法,而不能使用集合中的 remove()方法。否则将出现未知的错误。

Iterator iter = all.iterator(); 
while (iter.hasNext()) {// 判断是否有下一个元素 
    String str = iter.next(); // 取出当前元素 
    if (str.equals("C")) { 
        all.remove(str); // 错误的,调用了集合中的删除 
        iter.remove();   //迭代器中的remove
    } else { 
        System.out.print(str + "、"); 
    } 
}

terator 接口本身可以完成输出的功能,但是此接口只能进行由前向后的单向输出。如果要想进行双向输出,则必须 使用其子接口 —— ListIterator。

9.2ListIterator
双向输出的迭代接口
public interface ListIterator
extends Iterator

此接口中定义了以下的操作方法
1 void add(E e) 增加元素
2 boolean hasPrevious() 判断是否有前一个元素
3 E previous() 取出前一个元素
4 void set(E e) 修改元素的内容
5 int previousIndex() 前一个索引位置
6 int nextIndex() 下一个索引位置

List all = new ArrayList(); 
all.add("A"); all.add("B"); all.add("C"); all.add("D"); all.add("E"); 
ListIterator iter = all.listIterator(); 
System.out.print("从前向后输出:");
 while (iter.hasNext()) { 
System.out.print(iter.next() + "、"); 
} System.out.print("\n从后向前输出:");
 while (iter.hasPrevious()) { 
System.out.print(iter.previous() + "、"); 
}

10.Map接口

以上的 Collection 中,每次操作的都是一个对象,如果现在假设要操作一对对象,则就必须使用 Map 了,类似于以
下一种情况:
张三 123456 ·
李四 234567
所以要使用 Map 接口。里面的所有内容都按照 key->value 的形式保存,也称为二元偶对象。

1 void clear() 清空 Map 集合中的内容
2 boolean containsKey(Object key) 判断集合中是否存在指定的 key
3 boolean containsValue(Object value) 判断集合中是否存在指定的 value
4 Set<Map.Entry<K,V>> entrySet() 将 Map 接口变为 Set 集合
5 V get(Object key) 根据 key 找到其对应的 value
6 boolean isEmpty() 判断是否为空
7 Set keySet() 将全部的 key 变为 Set 集合
8 Collection values() 将全部的 value 变为 Collection 集合
9 V put(K key,V value) 向集合中增加内容
10 void putAll(Map<? extends K,? extends V> m) 增加一组集合
11 V remove(Object key) 根据 key 删除内容

Map 本身是一个接口,所以一般会使用以下的几个子类:HashMap、TreeMap、Hashtable

10.1 HashMap
HashMap 是 Map 的子类
此类继承了AbstracMap类,可以被克隆,可以被序列化

```java
Map map = new HashMap(); 
map.put(1, "张三A"); 
map.put(1, "张三B"); // 新的内容替换掉旧的内容 
map.put(2, "李四"); map.put(3, "王五"); 
String val = map.get(6); //找到就返回值,没有返回null
System.out.println(val);
Map<Integer,String> map = new HashMap<Integer, String>();
map.input(1,"张三");
map.input(2,"自身");
map.input(3,"防静");
Set<Integer> set = map.keySet(); //得到全部的key
Collection value = map.values(); // 得到全部的value
Iterator iter2 = value.iterator(); 
System.out.print("全部的key:"); 
while (iter1.hasNext()) { 
    System.out.print(iter1.next() + "、"); 
} 
System.out.print("\n全部的value:"); 
while (iter2.hasNext()) { 
    System.out.print(iter2.next() + "、"); 
}

在这里插入图片描述

10.1.1Map集合的输出

在 Collection 接口中,可以使用 iterator()方法为 Iterator 接口实例化,并进行输出操作,但是在 Map 接口中并没有此 方法的定义,所以 Map 接口本身是不能直接使用 Iterator 进行输出的。
因为 Map 接口中存放的每一个内容都是一对值,而使用 Iterator 接口输出的时候,每次取出的都实际上是一个完整的 对象。如果此时非要使用 Iterator 进行输出的话,则可以按照如下的步骤进行:
1、 使用 Map 接口中的 entrySet()方法将 Map 接口的全部内容变为 Set 集合
2、 可以使用 Set 接口中定义的 iterator()方法为 Iterator 接口进行实例化
3、 之后使用 Iterator 接口进行迭代输出,每一次的迭代都可以取得一个 Map.Entry 的实例
4、 通过 Map.Entry 进行 key 和 value 的分离
Map.Entry 本身是一个接口。此接口是定义在 Map 接口内部的,是 Map 的内部接口。此内部接口使用 static 进行定义, 所以此接口将成为外部接口。
在这里插入图片描述

Map map = new HashMap(); 
map.put("ZS", "张三"); 
map.put("LS", "李四"); 
map.put("WW", "王五"); 
map.put("ZL", "赵六"); 
map.put("SQ", "孙七"); 
Set<Map.Entry<String, String>> set = map.entrySet();// 变为Set实例 
Iterator<Map.Entry<String, String>> iter = set.iterator(); 
while (iter.hasNext()) {
 	Map.Entry me = iter.next();
 System.out.println(me.getKey() + " --> " + me.getValue()); 
}

Map 集合中每一个元素都是 Map.Entry 的实例,只有通过 Map.Entry 才能进行 key 和 value 的分离操作。

11.一对多关系

栗子:一个学校有多个学生,是一个典型的一对多的关系。

//定义学生类,一个学生属于一个学校
public class Student { 
    private String name; 
    private int age; 
    private School school;
    public Student(String name, int age) { 
        this.name = name; this.age = age; 
        } 
     public School getSchool() { 
         return school; 
     } 
     public void setSchool(School school) { 
         this.school = school; 
     } 
     public String toString() { 
         return "学生信息" + "\n" + "\t|- 姓名:" + this.name + "\n" + "\t|- 年龄:" + this.age; 
     } 
}
//定义学校类,一个学校有多个学生
import java.util.ArrayList;
import java.util.List;
public class School { 
    private String name; 
    private List allStudents = null;
    public School() { 
        this.allStudents = new ArrayList(); 
    }
    public School(String name) {
        this(); 
        this.name = name;
    }
    public List<Student> getAllStudents(){
        return allStudents;
    }    
public class TestDemo01 { 
public static void main(String[] args) { 
Student stu1 = new Student("张三", 10); 
Student stu2 = new Student("李四", 11); 
Student stu3 = new Student("王五", 12); 
School sch = new School("LAMP JAVA"); 
sch.getAllStudents().add(stu1); // 一个学校有多个学生 
stu1.setSchool(sch);// 一个学生属于一个学校 
sch.getAllStudents().add(stu2); // 一个学校有多个学生 
stu2.setSchool(sch);// 一个学生属于一个学校 
sch.getAllStudents().add(stu3); // 一个学校有多个学生 
stu3.setSchool(sch);// 一个学生属于一个学校 
System.out.println(sch); 
Iterator iter = sch.getAllStudents().iterator(); 
while (iter.hasNext()) { 
System.out.println(iter.next()); 
} 
System.out.println(stu1.getSchool()); 
} 
}

总结

1、 类集就是一个动态的对象数组,可以向集合中加入任意多的内容。
2、 List 接口中是允许有重复元素的,Set 接口中是不允许有重复元素。
3、 所有的重复元素依靠 hashCode()和 equals 进行区分
4、 List 接口的常用子类:ArrayList、Vector
5、 Set 接口的常用子类:HashSet、TreeSet
6、 TreeSet 是可以排序,一个类的对象依靠 Comparable 接口排序
7、 Map 接口中允许存放一对内容,key  value s
8、 Map 接口的子类:HashMap、Hashtable、TreeMap
9、 Map 使用 Iterator 输出的详细步骤

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值