一,Collection集合的简介:
集合的一些常用方法介绍及两种不同迭代方法的语句
package fighting;
import java.util.ArrayList;
import java.util.Iterator;
public class CollectionDemo {
/**
* 1,集合的add方法的参数类型时Object,以便于接收任意类型的对象。
* 2,集合中存放的不是对象实体,存储的是对象的引用(地址)。
*
* 什么是迭代器?
* 其实就是用于取出集合中的元素。
*/
public static void main(String[] args) {
Base_method();
method_2();
method_get();
}
//获取集合中的元素--迭代器接口Iterator
public static void method_get(){
ArrayList a1 = new ArrayList();
//1,添加元素
a1.add("aaa");
a1.add("bbb");
a1.add("ccc");
a1.add("ddd");
//获取迭代器,用于取出集合中的元素
Iterator it = a1.iterator();
while(it.hasNext()){
System.out.println(it.next());//aaa bbb ccc ddd
}
//for循环更优化:for循环结束,Iterator对象就释放了,而用while循环结束,Iterator对象仍占用内存
for(Iterator it1 = a1.iterator();it1.hasNext();){
System.out.println(it1.next());//aaa bbb ccc ddd
}
}
//retainAll removeAll
public static void method_2(){
ArrayList a1 = new ArrayList();
//1,添加元素
a1.add("aaa");
a1.add("bbb");
a1.add("ccc");
a1.add("ddd");
ArrayList a2 = new ArrayList();
//1,添加元素
a2.add("aaa");
a2.add("bbb");
a2.add("fff");
a2.add("ddd");
//取a1和a2的交集,存到a1
a1.retainAll(a2);
System.out.println("a1:"+a1);//a1:[aaa, bbb, ddd]
System.out.println("a2:"+a2);//a2:[aaa, bbb, fff, ddd]
//从a1中移除a1和a2的交集
a1.removeAll(a2);
System.out.println("a1:"+a1);//a1:[] 这里a1集合为空了,因为retainAll方法操作后,a1集合只剩下[aaa, bbb, ddd]
System.out.println("a2:"+a2);//a2:[aaa, bbb, fff, ddd]
}
//集合的一些基本方法
public static void Base_method(){
ArrayList a1 = new ArrayList();
//1,添加元素
a1.add("aaa");
a1.add("bbb");
a1.add("ccc");
a1.add("ddd");
a1.add("aaa");
//打印集合
System.out.println("原集合 "+a1);//原集合 [aaa, bbb, ccc, ddd, aaa]
System.out.println(a1.size());//5
//4,判断元素
System.out.println("ccc是否存在:"+a1.contains("ccc"));//ccc是否存在:true
//2,删除元素的返回值是boolean类型的,并且移除列表中首次出现的指定元素
a1.remove("aaa");
System.out.println("删除后 "+a1);//删除后 [bbb, ccc, ddd, aaa]
//3,清空集合
a1.clear();
System.out.println("clear "+a1);//clear []
System.out.println("清空后集合是否为空:"+a1.isEmpty());//清空后集合是否为空:true
}
}
二,List简介:
ArrayList,LinkedList和Vector的区别。
List增删改查的方法。
Iterator和ListIterator的用法与区别。
package fighting;
import java.util.ArrayList;
import java.util.*;public class ListDemo {
/**
* Collection
* |--List:元素是有序的,元素可以重复,因为该集合体系有索引。
* |--ArrayList:底层的数据结构使用的是数组结构。
* | 特点:查询速度很快,但是增删较慢。
* |--LinkedList:底层数据结构使用的是链表数据结构。
* | 特点:增删速度很快,但查询速度慢
* |--Vector:底层是数据数据结构。
* 和ArrayList相似,但是两者有区别:
* Vector线程同步,ArrayList线程不同步;
* ArrayList初始容量为10,元素个数超过10,再创建一个新的ArrayList对象,长度延长50%,
* 把原来的元素拷贝到新集合中,再添加元素,
* 而Vector是100%延长。
* |--Set:元素是无需的,元素不可以重复。
*
* List:
* 特有方法:凡是可以操作脚标的方法都是该体系特有的方法。
*
* 增:add(index,element)
* addAll(index,Collection)
* 删:remove(index)
* 改:set(index,element)
* 查:get(index)
* subList(from,to)
* listIterator()
*
* 知识点:List集合特有的迭代器:ListIterator是Iterator的子接口。
* 在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生异常java.util.ConcurrentModificationException
* 所以,在迭代时,只能用迭代器的方法操作元素,可是Iterator的方法有限,
* 只能对元素进行盘算,取出,删除的操作,
* 如果想要进行其他的操作如添加、修改等,就需要使用其子接口:ListIterator,
* ListIterator接口只能通过List集合的listIterator方法获取。
*/
public static void main(String[] args) {ArrayList a1 = new ArrayList();
//添加元素
a1.add("aaa");
a1.add("bbb");
a1.add("ccc");
a1.add("ddd");
System.out.println(a1);//[aaa, bbb, ccc, ddd]//1,在指定位置添加元素
a1.add(1,"fff");
System.out.println(a1);//[aaa, fff, bbb, ccc, ddd]
//2,删除指定位置的元素
a1.remove(2);
System.out.println(a1);//[aaa, fff, ccc, ddd]
//3,修改元素
a1.set(3, "hhh");
System.out.println(a1);//[aaa, fff, ccc, hhh]
//4.通过脚标获取元素
System.out.println(a1.get(3));//hhh
//5.使用脚标获取所有元素
for(int x=0;x<a1.size();x++){
System.out.println("a1("+x+")"+a1.get(x));//a1(0)aaa a1(1)fff a1(2)ccc a1(3)hhh
}
//6,使用迭代器获取元素
for(Iterator it = a1.iterator();it.hasNext();){
System.out.println(it.next());//aaa fff ccc hhh
}
//7,通过indexOf获取对象的位置
System.out.println("此时集合中的元素:"+a1);//此时集合中的元素:[aaa, fff, ccc, hhh]
System.out.println("通过indexOf获取对象的位置:"+a1.indexOf("ccc"));//通过indexOf获取对象的位置:2
//8.subList,包含开始,不包含结尾
System.out.println("subList:"+a1.subList(0, 2));//subList:[aaa, fff]
//9,列表迭代器,使用普通的iterator迭代器,有一定弊端,不能再迭代的时候进行增改的操作。
/*Iterator it = a1.iterator();
while(it.hasNext()){
Object obj = it.next();
//出现异常java.util.ConcurrentModificationException
//因为迭代器在操作集合,此时程序也要用集合的方法操作集合(a1.add("ooo"))
if(obj.equals("aaa")){
// a1.add("ooo");
it.remove();
}
System.out.println("列表迭代器:"+obj);//此时仍可以打印出aaa,因为
}
System.out.println(a1);
*/
ListIterator li = a1.listIterator();
System.out.println(li.hasPrevious());//false
System.out.println(li.hasNext());//true
while(li.hasNext()){
Object obj = li.next();
if(obj.equals("aaa")){
li.add("ooo");
}
}
System.out.println(li.hasPrevious());//true
System.out.println(li.hasNext());//false
System.out.println("列表迭代器"+a1);//列表迭代器[aaa, ooo, fff, ccc, hhh]
//倒序输出,hasPrevious方法的使用
while(li.hasPrevious()){
System.out.println(li.previous());
}
}}
三,Vector的使用
package fighting;
import java.util.Enumeration;
import java.util.Vector;
public class VectorDemo {
/**
* 枚举是Vector特有的取出方式.
* 其实枚举和迭代是一样的,它们是要实现相同的功能需求。
*
* 因为枚举的名称以及方法的名称都过长,所以渐渐被迭代器取代了。
*
*
*/
public static void main(String[] args) {
//小窍门:凡是方法带有element的,都是Vector的特有方法,比如addElement
Vector v=new Vector();
v.add("111");
v.add("222");
v.add("333");
v.add("444");
//枚举是Vector特有的取出方式
Enumeration en = v.elements();
while(en.hasMoreElements()){
System.out.println(en.nextElement());
}
}
}
四,LinkList的用法:jdk1.6版本和旧版本的常用方法的比较
package fighting;
import java.util.LinkedList;
public class LinkedListDemo {
/**
* LinkedList特有方法:
* addFirst()-->jdk1.6的offerFirst()
* addLast()-->jdk1.6的offerLast()
*
* getFirst()-->jdk1.6的peekFirst()
* 区别:返回此列表的第一个元素,如果此列表为空,则抛出异常NoSuchElementException
* peekFirst:获取但不移除此列表的第一个元素;如果此列表为空,则返回 null
* getLast()-->jdk1.6的peekLast()
* 区别:getLast:返回此列表的最后一个元素,如果此列表为空,则抛出异常NoSuchElementException
* peekLast:获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null
*
* removeFirst()-->jdk1.6的pollFirst
* 区别:removeFirst:
* pollFirst:获取并移除此列表的第一个元素;如果此列表为空,则返回 null
* removeLast()-->jdk1.6的pollLast
* 区别:removeLast:
* pollLast:获取并移除此列表的最后一个元素;如果此列表为空,则返回 null
*/
public static void main(String[] args) {
LinkedList link = new LinkedList();
link.addLast("111");
link.addLast("333");
link.addLast("222");
link.addLast("444");
//getFirst只是获取元素,removeFirst不仅获取元素还删除元素
System.out.println(link.getFirst());//111
System.out.println(link);//[111, 333, 222, 444]
System.out.println(link.removeFirst());//111
System.out.println(link);//[333, 222, 444]
//特有迭代
while(!link.isEmpty()){
System.out.println(link.removeFirst());//333 222 444
}
}
}
五,使用LinkedList模拟一个堆栈或者队列数据结构
package fighting;
import java.util.LinkedList;
public class LinkedListDemo2 {
/**
* 使用LinkedList模拟一个堆栈或者队列数据结构
*/
public static void main(String[] args) {
Queue q= new Queue();
q.myAdd("111");
q.myAdd("222");
q.myAdd("333");
q.myAdd("444");
while(!q.isNull()){
System.out.println(q.myGet());
}
Stack s= new Stack();
s.myAdd("111");
s.myAdd("222");
s.myAdd("333");
s.myAdd("444");
while(!s.isNull()){
System.out.println(s.myGet());
}
}
}
//队列:先进先出
class Queue{
private LinkedList link;
Queue(){
link=new LinkedList();
}
//每次都添加到队列末尾
public void myAdd(Object obj){
link.addLast(obj);
}
//每次移除第一个
public Object myGet(){
return link.removeFirst();
}
public boolean isNull(){
return link.isEmpty();
}
}
//堆栈:先进后出
class Stack{
private LinkedList link;
Stack(){
link=new LinkedList();
}
//每次添加到堆栈第一个,先进的就到了堆栈的底部
public void myAdd(Object obj){
link.addFirst(obj);
}
//每次移除第一个
public Object myGet(){
return link.removeFirst();
}
public boolean isNull(){
return link.isEmpty();
}
}
六,一个简单的小例子:去除ArrayList的重复元素
package fighting;
import java.util.ArrayList;
import java.util.Iterator;
public class ArraytListDemo {
/**
* 练习:去除ArrayList的重复元素
*/
public static void main(String[] args) {
ArrayList a1 = new ArrayList();
a1.add("111");
a1.add("111");
a1.add("222");
a1.add("333");
a1.add("333");
a1 = singleElement(a1);
System.out.println(a1);//[111, 222, 333]
}
public static ArrayList singleElement(ArrayList a1){
ArrayList newA1 = new ArrayList();
Iterator it = a1.iterator();
while(it.hasNext()){
Object obj = it.next();
if(!newA1.contains(obj)){
newA1.add(obj);
}
}
return newA1;
}
}
七,ArrayList集合中存储自定义对象,实现去重复
注意:ArrayList的add方法的参数Object类型,Person2对象在传入add方法时,向上转型为Object对象了
所以在用迭代器迭代的时候,it.next()返回的是Object类型,需要强转成Person2类型才可以调用Person2的方法
package fighting;
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListDemo2 {
/**
* 将自定义对象作为元素存到ArrayList集合中,并去除重复元素
* 比如:存储Person对象,同姓名同年龄视为同一个人,为重复元素
*
* 知识点:List对象判断元素是否相同,依据的是元素的equals方法
*
*/
public static void main(String[] args) {
ArrayList a1 = new ArrayList();
a1.add(new Person2("zhangsan01",10));
a1.add(new Person2("zhangsan02",11));
a1.add(new Person2("zhangsan03",12));
a1.add(new Person2("zhangsan04",13));
a1.add(new Person2("zhangsan03",12));
a1.add(new Person2("zhangsan04",13));
a1 = singleElement(a1);
Iterator it = a1.iterator();
//注意:ArrayList的add方法的参数Object类型,Person2对象在传入add方法时,向上转型为Object对象了
//所以在用迭代器迭代的时候,it.next()返回的是Object类型,需要强转成Person2类型才可以调用Person2的方法。
while(it.hasNext()){
Person2 p = (Person2)it.next();
System.out.println(p.getName()+"..." +p.getAge());
}
//remove方法:在删除以前,要先判断集合中有没有这个对象,也会调用equals方法
System.out.println("remove zhangsan03:"+a1.remove(new Person2("zhangsan03",12)));
System.out.println("删除以后的集合元素:");
Iterator it2 = a1.iterator();
while(it2.hasNext()){
Person2 p = (Person2)it2.next();
System.out.println(p.getName()+"..." +p.getAge());
}
}
public static ArrayList singleElement(ArrayList a1){
ArrayList newA1 = new ArrayList();
Iterator it = a1.iterator();
while(it.hasNext()){
Object obj = it.next();
//注意:contains方法底层调用的是对象的equals方法
if(!newA1.contains(obj)){
newA1.add(obj);
}
}
return newA1;
}
}
class Person2{
private String name;
private int age;
Person2(String name,int age){
this.name=name;
this.age=age;
}
@Override
public boolean equals(Object obj){
if(!(obj instanceof Person2)){
return false;
}
Person2 p =(Person2)obj;
//equals方法是对象自动调用的,每次添加对象都要调用这个方法
System.out.println(this.name+"..."+p.name);
if(this.name.equals(p.name)&&this.age==p.age){
return true;
}
return false;
}
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;
}
}
运行结果:
zhangsan02...zhangsan01
zhangsan03...zhangsan01
zhangsan03...zhangsan02
zhangsan04...zhangsan01
zhangsan04...zhangsan02
zhangsan04...zhangsan03
zhangsan03...zhangsan01
zhangsan03...zhangsan02
zhangsan03...zhangsan03 zhangsan03为什么没有和zhangsan04比呢?因为zhangsan03和第二个进来的zhangsan03比较完后,发现是相同的,所以就返回false了。
zhangsan04...zhangsan01
zhangsan04...zhangsan02
zhangsan04...zhangsan03
zhangsan04...zhangsan04 以上是6句添加语句调用equals方法的比较过程。
zhangsan01...10
zhangsan02...11
zhangsan03...12
zhangsan04...13 这是添加完后第一次迭代输出的结果。
zhangsan03...zhangsan01
zhangsan03...zhangsan02
zhangsan03...zhangsan03 这是remove方法调用equals方法的比较过程。
remove zhangsan03:true 这是remove方法返回的结果。
删除以后的集合元素:
zhangsan01...10
zhangsan02...11
zhangsan04...13 这是remove以后的结果,zhangsan03被删除了。
八,HashSet的用法:
HashSet的简单应用。
HashSet存储自定义对象,并去重复。研究HashSet保证元素唯一性的依据。
package fighting;
import java.util.HashSet;
import java.util.Iterator;
public class HashSetDemo {
/**
* Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复
* |--HashSet:底层数据结构是哈希表
* HashSet是如何保证元素唯一性的?
* 是通过元素的两个方法,hashCode和equals方法来完成。
* 如果元素的hashCode值相同,才会判断equals是否为true,
* 如果元素的hashCode值不同,不会调用equals。
* 所以记住:一般开发的时候定义对象,都重写hashCode和equals方法。
*
* 注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。
*
*/
public static void main(String[] args) {
//HashSet的简单应用
HashSet hs = new HashSet();
hs.add("111");
//add方法也是有返回值的
System.out.println(hs.add("222"));
System.out.println(hs.add("222"));
hs.add("333");
hs.add("444");
Iterator it = hs.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//HashSet存储自定义对象,并去重复
HashSet hsObj = new HashSet();
hsObj.add(new Person3("zhangsan01",22));//①
hsObj.add(new Person3("zhangsan02",23));//②
hsObj.add(new Person3("zhangsan02",23));//③
hsObj.add(new Person3("zhangsan03",24));//④
//对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法
System.out.println("contains..."+hsObj.contains(new Person3("zhangsan02",23)));//⑤
System.out.println("contains..."+hsObj.contains(new Person3("zhangsan04",23)));//⑥
hsObj.remove(new Person3("zhangsan01",22));//⑦
Iterator itObj = hsObj.iterator();
while(itObj.hasNext()){
Person3 p = (Person3)itObj.next();
System.out.println(p.getName()+"..."+p.getAge());
}
}
}
class Person3{
private String name;
private int age;
Person3(String name,int age){
this.name=name;
this.age=age;
}
@Override
public int hashCode(){
System.out.println(this.name+"...hashCode");
return name.hashCode()+age*37;
}
@Override
public boolean equals(Object obj){
if(!(obj instanceof Person3)){
return false;
}
Person3 p =(Person3)obj;
//equals方法是对象自动调用的,每次添加对象都要调用这个方法
System.out.println(this.name+"..equals.."+p.name);
if(this.name.equals(p.name)&&this.age==p.age){
return true;
}
return false;
}
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;
}
}
运行结果:
true
false
222
333
111
444 以上是简单应用的输出结果。
zhangsan01...hashCode
zhangsan02...hashCode
zhangsan02...hashCode
zhangsan02..equals..zhangsan02
zhangsan03...hashCode 这是①②③④四条添加语句调用hashCode和equals方法的过程。如果元素的hashCode值相同,还会判断equals是否为true。
zhangsan02...hashCode
zhangsan02..equals..zhangsan02 这是第一条contains语句⑤的比较过程。由于元素的hashCode相同,又进一步调用了equals方法。
contains...true 这是第一条contains语句⑤的返回值
zhangsan04...hashCode
contains...false 这两句是第二条contains语句⑥的比较过程和返回值。由于集合中不存在此元素,所以hashCode不同,不用再调用equals方法。
zhangsan01...hashCode
zhangsan01..equals..zhangsan01 这是remove语句的⑦的比较过程,调用remove方法,要先确定此元素是否在集合中存在,存在才可以remove。
zhangsan02...23
zhangsan03...24 这是调用remove方法后的迭代输出结果