package com.zhou.jihe;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
/**
* 一、 Java集合概述:
* 1.java集合就像一种容器,可以把多个对象的引用(而不是对象,对象还在堆内存里面,对象的引用是分配在栈内存的)放入容器中;
* 2.java集合类可以用于存储数量不等的多个对象,还可以用于保存具有映射关系的关联数组;
* 3.java的集合可分为Set、List、和Map三种体系:
* 3.1 Set:无序、不可重复的集合;
* 3.2 List:有序、可重复的集合;
* 3.3 Map:具有映射关系的集合;
* 4.在java5之前,java集合会丢失容器中所有对象的数据类型,把所有对象都当成Object类型处理;从java5增加了泛型以后,
* java集合可以记住容器中对象的数据类型;
*/
public class TestCollections {
public static void main(String[] args) {
/**
* 1.Collection接口:
* Collection接口是List、Set、Queue接口的父接口,该接口里定义的方法既可以操作Set集合,也可以用于操作
* List和Queue集合;
* 注意:Collection接口并不是Map接口的父接口,而Map接口是Collection接口的父接口;
* 实际上是由Map来定义产生的Collection接口,再由Collection接口产生 lterator迭代器接口;
*
* 这里将Collection接口里面的方法都作一一说,以后其他的接口就以这个为基础来自己用了;
*/
//测试下Collection接口里面所对应的方法;
//1.创建一个Collection接口的对象。
/**
* 接口的用法:需要找到接口的实现类,用这个实现类创建的对象来使用接口里面的方法,各个实现类有自己不同实现了接口的方法;
* 需要说一下,Collection是一个接口,这个接口我们用不了的,我们需要用它的一个对象,这个对象是什么呢,需要用到Collection接口的实现类,这里用ArrayList这个实现类。
*/
Collection collection = new ArrayList();
//接口的使用,创建接口对象:使用的就是java里的多态,相当于父类引用指向子类对象,这里是父接口的引用指向接口实现类的对象,我//这个collection对象能用到ArrayList类所特有的方法吗?很明显不能用到,我只能够用到这个Collection接口里面的方法;
//2.Collection接口重要方法说明:
/**
* 我们想一下,对于集合而言,里面的方法会分为哪几类呢?
* 2.1 用于添加元素的;
* add()用于添加对象;
* addAll()用于添加集合;
*/
Person p1 = new Person();
collection.add(p1);
collection.add(new Person());
//我们也可以这样写
Collection collection2 = new ArrayList();
collection2.add(new Person());
collection2.add(new Person());
//我可以这样加,用Collection接口中的addAll()方法添加一个集合
collection.addAll(collection2);
//Collection接口对象里面有个size()方法,我们可以知道这个集合里面有多少个元素,返回值是我这个集合的长度;
System.out.println(collection.size());
//这时集合中应该有4个
/**
* 2.2 用于访问集合的方法;
* size()获取集合的长度;
* iterator()对集合进行遍历的方法,这个方法可以得到 Iterator接口对象;
*
* Iterator:迭代器;
* 1.获取Iterator对象:调用Collection接口的iterator()方法就可以了;
* 2.使用while循环和Iterator遍历集合中的每个元素,具体使用Iterator接口的hasNext()和next()方法;
*/
//下面看看如何对collection进行遍历;
//1.首先得到一个Iterator对象;
Iterator iterator = collection.iterator();
//怎么用这个迭代器对象呢?
while(iterator.hasNext()){
//你这个对象里面还有下一个吗?
//如果有的话你就给我取出来吧;
Object obj = iterator.next();
//取完之后我们一个一个进行打印;
System.out.println(obj);
}
/**
* 2.3 移除集合中的元素:
* remove()方法移除某一个指定的对象,是通过equals()方法来判断要移除的那个
* 元素在集合中是否存在,以及是否能够成功移除,当我重写对象所在类的equals
* 方法,返回值为false时移除也会失败,即看我当前的这个对象和集合中的元素一
* 个一个的比,如果集合中有个对象和我当前这个对象一比是true,那么就能把这个
* 对象移除,否则移除不了,虽然说我这p1就是我当前放的这个对象,也不能移除
* 因为我以返回值为false的方式重写了equals方法;
* removeAll()方法移除一组;
* clear()方法使集合为空;
*/
//
collection.clear();//方法使集合为空;
//
boolean result = collection.remove(new Person());//移除失败,结果是false,因为你又创建了一个新的对象,这个对象在以前的/////集合中没有,要移除指定的对象就不能在添加集合元素的时候用匿名对象添加了;
//
boolean result = collection.remove(p1);
//
//removeAll()的道理和remove()是一样的
//
result = collection.removeAll(collection2);//p1和collection2的元素都会被移除,只剩下一个了;
//
System.out.println(result);
//
//
System.out.println(collection.size());//是0
/**
* 2.4 用于检测集合的方法:
* 我这集合中是不是有某个指定的元素,我这个集合中是不是有某一组指定的元素,我这个集合是不是空,等等;
* contains()
* containsAll()
* isEmpty()
*/
System.out.println(collection.contains(new Person()));
//new 的肯定不包含,false
System.out.println(collection.contains(p1));
//true
System.out.println(collection.containsAll(collection2));
//true
System.out.println(collection.isEmpty());
//false
//
collection.clear();
System.out.println(collection.isEmpty());
//true
/**
* 2.5 其他方法:
* toArray()方法返回集合对应的数组对象;
* 返回的是T[]的toArray(T[] e)跟泛型相关的方法,涉及到泛型,后面再说;
*
* equals()方法比较两个集合是否相等,一比长度,二比集合中的元素是不是相等。
* hasCode()方法返回的是集合的一个哈希码
*
*
*/
Object[] objs = collection.toArray();
System.out.println(objs.length);
//4
Person p2 = new Person();
//
Collection collection3 = new ArrayList();
Collection collection3 = new HashSet();
collection3.add(p1);
collection3.add(p2);
//
Collection collection4 = new ArrayList();
Collection collection4 = new HashSet();
//
collection4.add(p1);
//
collection4.add(p2);
collection4.add(p2);
collection4.add(p1);
//
System.out.println(collection3.equals(collection4));//true
//
System.out.println(collection3.equals(collection4));//换了顺序之后,false
,这跟具体是 ArrayList实现类有关系
System.out.println(collection3.equals(collection4));//换成HashSet为Collection接口的实现类就是true,与顺序无关
/**
* 使用增强for循环的方式来对集合进行遍历:
*/
for(Object obj:collection){
System.out.println(obj);
}
}
}
package com.zhou.jihe;
public class Person {
//当我重写equals方法集合的移除也会失败
//
@Override
//
public boolean equals(Object obj) {
//
// TODO Auto-generated method stub
////
return super.equals(obj);
//
return false;
//
}
//用IDE直接生成hashCode()和equals()方法
//hashCode()方法决定着我们放的这个元素在集合中的位置,如果两个元素比较equals()方法返回fasle的话,那么hashCode()方法返//回值应该也不相等,应该放在两个位置;
//反过来,如果equals()方法返回的true的话,那么hashCode()返回值应该也相等,它们是同一个元素,应该放在同一个地方;
/**
* 正常情况下我们这么来做:两个对象的equals()方法返回true,hashCode()方法返回值必相等;
* 通常情况下,我们使用eclipseIDE帮我们生成hashCode()和equals()方法就可以;
* 学习的时候我们可以这样来试一下,不建议开发的时候这样来做,如果equals()方法返回true,它两是同一个元素,但是hashCode()值不一样,那么这两个对象都可以放到这个集合里面去,这个是矛盾的事
*/
/**
* hashCode()方法的要求:
* HashSet集合判断两个元素相等的标准:两个对象通过equals()方法方法比较返回true相等,并且两个对象的hashCode()方法返回值也相等。
* 如果两个对象通过equals()方法返回true,这两个对象的hashCode值也应该相同;
*
* 重写hashCode()方法的基本原则:
* 1.在程序运行时,同一个对象多次调用hashCode()方法应该返回相同的值;
* 2.当两个对象的equals()方法比较返回true时,这两个对象的hashCode()方法的返回值也应该相等;
* 3.对象中用作equals()方法比较的(Field)区域,都应该用来计算hashCode值;
*
*/
//
private static int init = 0;
@Override
public int hashCode() {
//这个hashCode值和age的值联合到一起来返回的一个结果
final int prime = 31;
//用这个素数是为了防止name的hashCode值和age的值不一样,但是有可能age和name的hashCode值相加//得到的那个数可能一样的情况;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
//
return init++;//不允许
}
//这个是一个一个属性比的,这个是IDE自动帮我们生成的equals()方法,这个是可信赖的;
@Override
public boolean equals(Object obj) {
if (this == obj)
//如果这两个对象是一个的话,返回true
return true;
if (obj == null)
//如果传的这个对象是空的话,返回fasle
return false;
if (getClass() != obj.getClass())//如果类型不一致的话,返回false
return false;
Person other = (Person) obj;
//否则,强转
if (age != other.age)
//如果年龄不一样的话,返回false
return false;
if (name == null) {
//如果名字为空
if (other.name != null)
//另外一个的名字不为空返回fasle
return false;
} else if (!name.equals(other.name))
//如果名字不一样的话,返回fasle
return false;
return true;
//否则,最后返回true,表示一样;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
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;
}
private String name;
private int age;
}