Java学习笔记之集合(一):Collection集合的方法

package com.collection;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

import org.junit.Test;

/*
 * 数组:存储同一种数据类型的集合容器;
 * 
 * 数组的特点:
 * 	1、只能存储同一种数据类型的容器;
 * 	2、一旦初始化,长度固定;
 * 	3、数组中的元素与元素之间的内存地址是连续的;
 * 
 * 注意:Object类型的数组可以存储任意类型的数据(特殊的数组);
 * 
 * 集合的引入:
 * 需求:收集全班同学的兴趣爱好。
 * 如果使用数组存储:
 * 	String[] arr = new String[]; // 问题:数组长度没法确定;太短不够,太长浪费;
 * 
 * 集合:存储对象数据的集合容器;
 * 特点:
 * 	1、集合可以存储任意类型的对象数据;数组只能存储同一种类型的数据;
 * 	2、集合的长度是不固定的,可以改变;数组的长度是固定的,不能改变;
 * 
 * Collection:单列集合的根接口,定义了集合的规范;
 * 	List:如果是实现了List接口的集合类,具备的特点:有序,可重复;
 * 	Set:如果是实现了Set接口的集合类,具备的特点:无序,不可重复;
 * 
 * Collection接口中的方法:
 * 	增加:
 * 		add(E e):向集合中添加元素,添加成功返回true,添加失败返回false;
 * 		addAll(Collection<?> c):将一个集合中的元素添加到另一个集合中;
 * 	删除:
 * 		clear():清空集合中的元素;
 * 		remove(Object o):删除集合中指定的元素;删除成功返回true,删除失败返回false; 
 * 		removeAll(Collection<?> c):删除集合中与另一个集合的交集元素;
 * 		retainAll(Collection<?> c):保留集合中与另一个集合的交集元素,其他元素全部删除; 
 * 	查看:
 * 		size():查看元素的个数;
 * 	判断:
 * 		isEmpty():判断集合是否为空; 
 * 		contains(Object o):判断集合中是否存在指定的元素;
 * 		containsAll(Collection<?> c):如果集合中包含另一个集合中的所有元素,则返回true;
 * 	迭代:
 * 		toArray():返回集合中所有元素的数组;
 * 		iterator():返回一个迭代器Iterator;
 * 	迭代器的方法:
 * 		1、hasNext():判断迭代器中是否有元素可遍历,如果有返回true,没有返回false;
 * 		2、next():获取元素;
 * 		3、remove():移除迭代器最后一次返回的元素;
 */

public class Demo1 {
	
	@Test
	public void test1(){
		// Object类型的数组
		Object[] arr = new Object[10];
		// 可以存储任意类型的数据
		arr[0] = "abc";
		arr[1] = 'e';
		arr[2] = 123;
	}

	// 添加方法
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Test
	public void test2(){
		// 集合可以存储任意类型的数据,并且集合的长度是可变的;
		Collection c = new ArrayList();
		c.add("abc");
		c.add(123);
		c.add(3.14);
		System.out.println("集合的元素:" + c);	// 集合的元素:[abc, 123, 3.14]
		
		Collection c2 = new ArrayList();
		c2.add("张三");
		c2.add("李四");
		c.addAll(c2);	// 将c2集合中的元素添加到c集合中
		System.out.println("集合的元素:" + c); // 集合的元素:[abc, 123, 3.14, 张三, 李四]
	}
	
	// 删除方法
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Test
	public void test3(){
		Collection c = new ArrayList();
		c.add("张三");
		c.add("李四");
		c.add("王五");
		
		Collection c2 = new ArrayList();
		c2.add("赵六");
		c2.add("张三");
		
//		c.clear(); // 清空集合c中的元素
		
//		boolean b = c.remove("李四"); 	// 删除集合中的"李四",元素存在,删除成功;
//		boolean b = c.remove("李三");		// 删除集合中的"李三",元素不存在,删除失败;
//		System.out.println("删除成功了吗?" + b);
		
//		c.removeAll(c2); 	// 从c集合中删除与c2集合的交集元素;删除的是调用者集合中的元素;
		c.retainAll(c2);	// 保留c集合中与c2集合的交集元素,其他元素全部删除;
		
		System.out.println("c集合中的元素:" + c);
		System.out.println("c2集合中的元素:" + c2);
		System.out.println("c2集合中元素的个数:" + c2.size());
	}
	
	// 判断方法
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Test
	public void test4(){
		Collection c = new ArrayList();
		c.add("张三");
		c.add("李四");
		c.add("王五");
		
//		c.clear();		
		System.out.println("集合是否为空:" + c.isEmpty()); // 集合为空返回true,不为空返回false;		
		System.out.println("存在该元素吗?" + c.contains("田七")); // 存在返回true;不存在返回false;
		
		// 在集合中添加自定义元素
		Collection c2 = new ArrayList();
		c2.add(new Person(1, "张三"));
		c2.add(new Person(2, "李四"));
		c2.add(new Person(3, "王五"));
		System.out.println("集合中的自定义元素:" + c2);
		
		/*
		结果为:false,即集合不存在该元素,为什么?
		可以从源码查看,那么查看谁的源码?因为在多态的情况下,使用的永远是实现类的方法,所以此处查看ArrayList类的方法;
		contains源码为:可以看出,调用的是indexOf()方法,那么继续查看indexOf方法;
		public boolean contains(Object o) {
	        return indexOf(o) >= 0;
	    }
	    indexOf()方法源码为:
	    public int indexOf(Object o) {
	        if (o == null) {
	            for (int i = 0; i < size; i++)
	                if (elementData[i]==null)
	                    return i;
	        } else {
	            for (int i = 0; i < size; i++)
	                if (o.equals(elementData[i]))
	                    return i;
	        }
	        return -1;
	    }
		从indexOf源码可以看出,当用于比较的对象,即Object对象不为空时,实际上调用的是传入对象的equals方法,
		然后将传入的对象与集合中的元素依次比较;而equals方法默认比较的是对象在内存中的地址,所以此处
		新new的Person对象不存在集合中;
		那么现在要求只要id一样,就是同一个对象,该怎样实现?
		重写equals方法,判断id一样时,就认为是同一个对象;
	    */
		System.out.println("存在该自定义元素吗?" + c2.contains(new Person(2, "李四"))); 
		
		// containsAll():如果集合中包含另一个集合中的所有元素,则返回true;
		Collection c3 = new ArrayList();
		c3.add(new Person(1, "张三"));
		c3.add(new Person(2, "李四"));
		System.out.println("c2包含c3中的所有元素吗?" + c2.containsAll(c3)); // true
		
		c3.add(new Person(7, "田七"));
		System.out.println("此时c2还包含c3中的所有元素吗?" + c2.containsAll(c3)); // false
	}
	
	// 迭代方法
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Test
	public void test5(){
		Collection c = new ArrayList();
		c.add("张三");
		c.add("李四");
		c.add("王五");
		Object[] arr = c.toArray(); // 把集合中的元素全部存储到一个Object数组中;
		System.out.println("数组中的元素:" + Arrays.toString(arr));
		
		Collection c2 = new ArrayList();
		c2.add(new Person(1, "张三"));
		c2.add(new Person(2, "李四"));
		c2.add(new Person(3, "王五"));
		// 需求:取出编号为2的人员的信息;
		Object[] arr2 = c2.toArray();
		for (int i = 0; i < arr2.length; i++){
			Person p = (Person) arr2[i];
			if (p.id == 2){
				System.out.println("id为2的元素:" + p);
			}
		}

		System.out.println("------------");
		
		// 遍历集合c2中的所有元素:方式一
		for (int i = 0; i < arr2.length; i++){
			Person p = (Person) arr2[i];
			System.out.println(p);
		}
		
		System.out.println("------------");
		
		// 遍历集合c2中的所有元素:方式二
		// 问题:iterator()方法返回的是一个接口类型,为什么可以直接调用方法使用呢?
		// 查看ArrayList类中的iterator()方法源码:
		// public Iterator<E> iterator() {
	    //    return new Itr();
	    // }
		// private class Itr implements Iterator<E> {}
	    // 可以看出,iterator()方法实际上返回的是Iterator接口的实现类的对象;
		Iterator it =  c2.iterator(); // 返回一个迭代器
		while (it.hasNext()){
			Person p = (Person)it.next();
			System.out.println(p);
		}

		System.out.println("------------");
		
		// remove():移除迭代器最后一次返回的元素;
		Iterator it2 = c2.iterator();
		
		// 此处直接移除,会出现异常:java.lang.IllegalStateException,因为迭代器还没有返回元素;
//		it2.remove(); 
		
		it2.next();		// 此处返回的是第一个元素;
		it2.remove();	// 那么此处移除的就是第一个元素;
		
		System.out.println("集合中的元素:" + c2);
	}
	
}

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

	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + "]";
	}

	// 重写equals方法,要求只要id一样,就是同一个对象
	@Override
	public boolean equals(Object obj) {
		Person p = (Person)obj;
		return this.id == p.id;
	}
	
	// Java中的规范:一般重写equals()方法时,都要重写hashcode()方法;
	@Override
	public int hashCode() {
		return this.id;
	}
	
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值