您的位置:首页 > 编程语言 > Java开发

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

2017-09-20 11:24 513 查看
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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐