集合框架

集合框架体系图
在这里插入图片描述
体系图解释如下
1.所有集合类都位于java.util包下。Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类。
2. 集合接口:8个接口(短虚线表示),表示不同集合类型,是集合框架的基础。
3. 抽象类:5个抽象类(长虚线表示),对集合接口的部分实现。可扩展为自定义集合类。
4. 实现类:10个实现类(实线表示),对接口的具体实现。
5. Collection 接口是一组允许重复的对象。
6. Set 接口继承 Collection,集合元素不重复。
7. List 接口继承 Collection,允许重复,元素有序。
8. Map接口是键-值对象,与Collection接口没有什么关系。
9.Set、List和Map可以看做集合的三大类:
List集合是有序集合,集合中的元素可以重复,访问集合中的元素可以根据元素的索引来访问。
Set集合是无序集合,集合中的元素不可以重复,访问集合中的元素只能根据元素本身来访问。
Map集合中保存Key-value对形式的元素,访问时只能根据每项元素的key来访问其value。

集合的特点:
1.集合能够对数据进行增加删除修改查询的操作
2.集合能够存储引用类型,如果是基本类型可以是包装类类型
3.集合的长度是可变的
4.部分集合是有序的,部分集合是无序的 (这里的有序指的是存储有序,并不是排序)
5.部分集合是唯一的,部分集合是可重复 (11, 22 ,33, 33, 22)
6.部分集合是可排序的,部分集合是不可排序的 33 44 55 11 -> 11 33 44 55
7.部分集合是线程安全的,部分集合是线程不安全 (synchronized)
集合应该设计成一个类,还是一个框架?
集合框架应该设计成一个接口,不同的集合的实现不一样,那么效率不一样,
特点不一样,我们可以自由选取

集合与数组的区别:
1、长度
数组的长度是固定不变的
集合的长度可以根据实际需要改变,根据你存入的数据动态的增加
2、内容
数组存储的是同一种类型,例如:一个数组里面全是int类型,就不能有其他像double,string类型存在
3、数据类型
数组可以存储基本数据类型(byte、short、int、long、float、double、boolean、char),也可以存储引用类型(数组、接口、类)
集合只能存储引用类型
这里注意的是:虽然集合不能存储基本数据类型,但是可以存储基本类型对应的包装类型(Byte、Short、Integer、Long、Float、Double、Boolean、Character)
数据结构: 数据的存储方式。
常见的和集合相关的数据结构: 数组,栈,队列,链表,哈希表,二叉树
存储方式不一样决定了该集合的性能效率不一样

集合有以下功能:
1.增加功能
boolean add(E e)
boolean addAll(Collection<? extends E> c)
2.删除功能
void clear()
boolean remove(Object o)
boolean removeAll(Collection<?> c)
3.修改功能
4.查询功能
Iterator iterator()
Object[] toArray()
T[] toArray(T[] a)
5.获取功能
int size()
6.判断功能
boolean contains(Object o)
boolean containsAll(Collection<?> c)
boolean isEmpty()
7.其他功能
boolean retainAll(Collection<?> c) 取交集
返回原集合是否发生改变
改变了返回true
没改变返回false

举例代码如下

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo01 {
	public static void main(String[] args) {
		Collection c = new ArrayList();
		c.add("张三");
		c.add("李四");
		c.add("王五");
		c.add("赵六");
		System.out.println(c); // [张三, 李四, 王五, 赵六]
		
		// boolean addAll(Collection c)
		Collection c2 = new ArrayList(); 
		c2.add("曹操");
		c2.add("萨达姆");
		c2.add("本拉登");
		c.addAll(c2);
		
		System.out.println(c);
		
		// boolean remove(Object o) 
		System.out.println("remove: " + c.remove("张三"));
		System.out.println(c);
		// boolean removeAll(Collection<?> c) 
//		System.out.println("removeAll: " + c.removeAll(c2));
//		System.out.println(c);
		
		// void clear() 
//		c.clear();
//		System.out.println(c);
		
		System.out.println(c.size());
		
		System.out.println("contains: " + c.contains("李四"));
		System.out.println("contains: " + c.contains("曹操"));
		System.out.println("contains: " + c.contains(""));
		System.out.println("containsAll: " + c.containsAll(c2));
		System.out.println("isEmpty: " + c.isEmpty());
		
		Collection c3 = new ArrayList();
//		c3.add("张三");
//		c3.add("李四");
//		c3.add("王五");
//		c3.add("赵六");
//		c3.add("曹操");
//		c3.add("萨达姆");
//		c3.add("本拉登");
//		c3.add("秦始皇");
		System.out.println(c);
		System.out.println(c3);
		System.out.println("retainAll:" + c.retainAll(c3));
		System.out.println("c:" + c);
		
	}

}

集合的遍历
java8.0以后,提供了4中遍历集合的方法,循环、迭代、foreach

一组集合例子

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

        listNames.add("张三");
        listNames.add("李四");
        listNames.add("王五");
        listNames.add("赵钱");
        listNames.add("孙李");
    }

1、循环方式

for(i = 0; i < listNames.size();i++){
	 String name = listNames.get(i);
     System.out.println(name);
}

缺点:基于索引形式存储元素,需提前知道集合的大小,通过索引方式访问其元素的方法,该方法不能用于所有集合
迭代器原理:
在获取迭代器的时候,会创建一个集合的副本,同时创建一个指针指向迭代器迭代集合的起始位置
在这里插入图片描述
2、迭代方式
List上迭代遍历

Iterator<String> itr = listNames.iterator();//创建迭代器对象
	//判断迭代器中是否还有下一个元素
	while (itr.hasNext()) {
		   String name = itr.next();
		   System.out.println(name);
}

Set上迭代遍历

Set<String> set = new HashSet<>();

        set.add("a");
        set.add("b");
        set.add("c");
        set.add("d");

Iterator<String> itr = set.iterator();

      while (itr.hasNext()) {
           String letter = itr.next();
           System.out.println(letter);
       }

Map上迭代遍历

 Map<String, Integer> grade = new HashMap<>();

        grade.put("Operating System", 90);
        grade.put("Computer Network", 92);
        grade.put("Software Engineering", 90);
        grade.put("Oracle", 90);

        Iterator<String> itr = grade.keySet().iterator();

        while (itr.hasNext()) {
            String key = itr.next();
            Integer value = grade.get(key);
            System.out.println(key + "=>" + value);
        }

3、加强for循环

for(String s : listNames){
	System.out.println(s);
}

注意:加强for循环实际在背后使用的也是迭代器。编译时java编译器会将增强型语法转换为迭代器构造
4、使用Lambda表达式的foreach

 listNames.forEach(name -> System.out.println(name));

forEach方法与之前的方法最大的区别:
在之前的方法中(经典for循环,迭代器和加强for循环),程序员可以控制集合是如何迭代的。迭代代码不是集合本身的一部分 - 它是由程序员编写的 - 因此称为外部迭代。
相比之下,新方法将迭代代码封装在集合本身中,因此程序员不必为迭代集合编写代码。 相反,程序员会在每次迭代中指定要做什么 - 这是最大的区别! 因此术语内部迭代:集合处理迭代本身,而程序员传递动作 - 即每次迭代需要做的事情。

并发修改异常
java.util.ConcurrentModificationException
异常名称: 并发修改异常
产生原因: 表示在使用迭代器的同时,使用原集合修改了元素
解决办法:
1.只操作原集合
toArray
普通for
2.只操作迭代器
使用ListIterator
注意:
foreach遍历集合底层也是使用了迭代器不能够解决并发修改异常
举例代码如下

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo3 {
		public static void main(String[] args) {
			Collection c = new ArrayList();
			c.add("希特勒");
			c.add("杨贵妃");
			c.add("貂蝉");
			c.add("赛西施");
			//遍历集合方式一
			Iterator it = c.iterator();
			while (it.hasNext()) {
				Object oj = it.next();
				String s = (String) oj;
				if (s.equals("杨贵妃")) {
					c.remove("杨贵妃");//在使用迭代器的同时,使用原集合修改了元素
				}
			}
//			//遍历集合方式二
//			Object[] objs = c.toArray();
//			for (Object oj : objs) {
//				String s = (String) oj;
//				if (s.equals("杨贵妃")) {
//					c.remove("杨贵妃");
//				}
//			}
//			//遍历集合方式三
//			for (Object oj : c) {
//				String s = (String) oj;
//				if (s.equals("杨贵妃")) {
//					c.remove("杨贵妃");
//				}
//			}
//			//遍历集合方式四
//			for (Iterator iterator = c.iterator(); iterator.hasNext();)
//			{
//				Object oj = iterator.next();
//				String s = (String)oj;
//				if (s.equals("杨贵妃"))
//					c.remove("杨贵妃");
//			}

			for(Iterator iterator = c.iterator();iterator.hasNext();) System.out.println(iterator.next());

			
	}
}

举例:使用集合存储学生对象,并且去除重复学生, 学生编号相同即为同一个学生
代码实现

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo04 {
	public static void main(String[] args) {
		// 1.创建容器对象
		Collection c = new ArrayList();
		// 2.创建学生元素对象
		Student s1 = new Student("1001", "张三", 18);
		Student s2 = new Student("1002", "李四", 18);
		Student s3 = new Student("1003", "王五", 18);
		Student s4 = new Student("1003", "王五丰", 18);
		Student s5 = new Student("1004", "赵六", 18);
		Student s6 = new Student("1005", "孙七", 18);
		// 3.将学生存储到集合中
		c.add(s1);
		c.add(s2);
		c.add(s3);
		c.add(s4);
		c.add(s5);
		c.add(s6);
		c.add("hello");//存储字符串类型
		c.add(100);//存储Integer类
		
		// 遍历集合
		Iterator it = c.iterator(); //创建迭代器对象
		while (it.hasNext()) {
			Object oj = it.next();
			//访问Student类中的方法作向下转型判断
			if (oj instanceof Student) {
				Student s = (Student) oj;
				System.out.println(s);
			} else if (oj instanceof String) {
				String s = (String) oj;
				System.out.println(s);
			}
			
			System.out.println(((Student)it.next()).getName() + "|" + ((Student)it.next()).getAge());
		}
		
		// 去除重复元素
		// 1.创建一个新的集合
		Collection c2 = new ArrayList();
		// 2.遍历旧集合
		for (Object oj : c) {
		// 3.判断新集合中是否存在这个元素
			if (!c2.contains(oj)) {
				// 4.如果新集合中不存在该元素就存储到集合中
				c2.add(oj);
			}
		}
		System.out.println("------------------");
		// 地址传递
		c = c2;
		System.out.println("------------------");
		for (Object object : c) {
			System.out.println(object);
		}
		
	}
}

class Student {
	private String id;
	private String name;
	private Integer age;
	public Student() {
		super();
	}
	public Student(String id, String name, Integer age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
	
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值