java基础--Collection List

来源:互联网 发布:htc x9网络 编辑:程序博客网 时间:2024/05/13 14:12

package com.zemeng;


import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Collection;

import java.util.Date;

import java.util.Iterator;

import java.util.Random;


public class ArrayDemo {


public staticvoid main( String[]argv ){

/* 集合:

 * 1.1 什么是集合

 * 存储对象的容器,面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,存储对象;集合是存储对象最常用的一种方式;

 *   集合的出现就是为了持有对象。集合中可以存储任意类型的对象,而且长度可变。在程序中有可能无法预知需要多少个对象,那么用数组来装对象的话,

 *   长度不好定义,而集合解决了这样的问题;

 * 

 * 1.2 集合和数组的区别

 * 数组和集合类都是容器类

 *  (1)数组长度是固定的,集合长度是可变的; 

 *  (2)数组中可以存储基本数据类型,集合只能存储对象; 

 *  (3)数组中存储数据类型是单一的,集合中可以存储任意类型的对象;

 * 

 *    数组的缺点:

 *    存储类型单一的数据容器,操作复杂 ( 数组一旦声明好,长度就不可变 )

 * 

 * 

 * 1.3 集合的分类:

 * 

 *   集合做什么: ( 增删改查 )

 * (1) 增: 将对象添加到集合

 * (2) 删: 从集合中删除对象

 * (3) 改: 从集合中替换对象 

 * (4) 查: 从集合中查找对象

 * 

 *   注意:  集合金额数组中存放的都是对象的引用, 而非对象本身;

 * 

 *   java工程师对不同的容器进行了定义,虽然容器不同,但是还是有一些共性可以抽取;最后抽取了一个顶层接口,然后形成一个集合框架.

 *   从顶层学起,顶层里面具有共性,最基本的行为. 集合的最顶层是 Collection;

 * 

 * 

 *   |---Collection   

 * |------List  

 * |------Set   

 * |------Map

 * 

 * 

 *   |---Collection   单列集合

 * 

 * 

 * |----- List  

 *    有存储顺序,元素可重复;

 * 

 * |-------ArrayList  

 *   数组实现,查找快,增删慢( 由于是数组实现,在增和删的时候会牵扯到数组的增容以及拷贝元素。数组

 *     是可以直接按索引查找,所以查找时较快 );

 * 

 * |-------LinkedList   

 *                            链表实现,增加时只要让前一个元素记住自己就可以,删除时让前一个元素记住后一个元素,这样增删效率高

 * 但是查询时需要一个一个遍历,效率低;

 * 

 * |-------Vector  

 *                            和ArrayList原理相同,但线程安全,效率略低和ArrayList实现方式相同,但是考虑了线程安全问题,

 * 所以效率偏低;

 * 

 * 

 * 

 * 

 * |------ Set     

 *   无存储顺序,不可重复;

 * 

 * |-------HashSet

 * 

 * |-------TreeSet

 * 

 * |-------LinkedHashSet

 *  

 * 

 * 

 * 

 * |------ Map  键值对

 * 

 * |-------HashMap

 * 

 * |-------TreeMap

 * 

 * |-------HashTable

 * 

 * |-------LinkedHashMap

 * 

 * 

 * 

 * 

 * 1.4 什么时候该使用什么样的集合

 * 

 * Collection    我们需要保存若干个对象的时候使用集合;( 保存若干个对象 )

 *  

 * List          如果我们需要保留存储顺序,并且可以保留重复元素,使用List。

 *  (1)如果查询较多,那么使用 ArrayList;

 *  (2)如果存取较多,那么使用 LinkedList;

 *  (3)如果需要线程安全,那么使用Vector;

 * 

 * Set           如果我们不需要保留存储顺序,并且需要去掉重复元素,使用Set.

 *   (1)如果我们需要将元素排序,那么使用TreeSet,如果不需要排序,使用HashSet,Hashset比TreeSet效率高;

 *   (2)如果我们需要排序,又要过滤掉重复元素,那么使用LinkedHashSet;

 * 

 * 

 * 

 * 

 * 

 * 

 *  2. 集合类 ( Collection )   接口

 * 

 * |---- Collection接口有两个子接口:   //描述所有接口的共性

 *  

 * |----- List ( 链表/线性表 )    //可以有重复元素的集合

 * 

 * |----- Set  ( 集合 )          //不可以有重复元素的集合

 * 

 *    特点:

 *  Collection中描述的是集合共有的功能;

 * List 可存放重复元素, 元素存取是有序的;

 * Set 不可以存放重复元素,元素存取是无序的;

 * 

 * 

 * 

 * 

 * 2.1 Collection接口的共性方法:

 * 

 * (1) 增加:  

 * 1.  boolean add(E e);

 *    将指定对象存储到容器中; add方法的参数类型是Object,便于接受任意对象

 *    ( 如果使用add()方法添加了一个集合元素,那么仅当做一个元素对象被添加进集合 )

 * 

 * 2.  boolean addAll(Collection<? extends E> c);  

 *    将指定集合中的元素添加到调用该方法和集合中 (将集合中的元素,使用遍历,一个个添加到集合中 )

 * 

 * (2) 删除:

 * 3.  boolean remove(Object o);  删除指定的元素 

 * 4.  boolean removeAll(Collection<?> c); 删除指定子集中存在与该集合中相同的元素 (不一定要是子集,只要有相同元素,就删除该元素)

 * 5.  void clear();   清空集合中的所有元素

 * 

 * (3) 判断:

 * 6.  boolean isEmpty()   判断集合是否为空;

 * 7.  boolean contains( Object o )  判断集合中是否包含指定对象;

 * 8.  boolean containsAll( Collection list )  判断集合中是否包含指定子集;    使用equals()判断两个对象中所有元素是否相等;

 * 

 * (4) 大小:

 * 9. int size()  返回集合容器的大小;  ( String->length(),  Array->length )

 * 

 * (5) 转换成数组:

 * 10. Object[] toArray()   集合转换成数组;


 * */

/*  1. 增加  */

//add( E e ); 当做一个元素添加进集合

Collection<String> list =new ArrayList<String>();

list.add("计算机网络");

list.add("现代操作系统");

list.add("java编程思想");

System.out.println(list );

 

//boolean addAll(Collection<? extends E> c);  添加一个集合;

Collection<String> list2 =new ArrayList<String>();

list2.add("java编程思想");

list2.add("java核心技术");

list2.addAll(list);//将集合中的所有元素通过遍历,一个一个添加进集合中;

list2.add("java语言程序设计");

System.out.println(list2);


/* 2. 删除 */

//boolean remove(Object o);  删除指定的元素

boolean remove = list2.remove("java核心技术");

System.out.println("是否删除成功:"+remove );

//boolean removeAll(Collection<?> c); 删除指定子集中存在与该集合中相同的元素

boolean removeAll = list2.removeAll(list);

System.out.println(removeAll );

System.out.println(list2 );

//void clear();  清空集合中所有的元素

list2.clear();

/* 3. 判断 */

//boolean isEmpty(); 判断集合中元素个数是否为空  ;   判断String是否为空 boolean isEmpty()

booleanisEmpty =list2.isEmpty();  

System.out.println("是否为空:"+isEmpty );

//集合是否包含某个元素: boolean contains(Object o);

booleancontains =list.contains("java编程思想");

System.out.println("是否包含这个元素:"+contains );

//集合是否包含某个子集: boolean containsAll(Collection<?> c);

booleancontainsAll =list.containsAll(list2);

System.out.println("是否包含这个子集:"+containsAll );


/* 4. 大小 */

int length = list.size();

System.out.println(length );


/* 5. 转换成数组 */

Object[] arrStrings =list.toArray();  

System.out.println( Arrays.toString(arrStrings) );

/* 2.1.6 练习: 集合中添加自定义对象

 * 

 *   1.创建集合对象

 *   2.创建Person对象

 *   3.集合中添加一些Person对象

 *   4.删除指定Person对象

 *   5.删除所有Person对象

 *   6.判断容器中是否还有Person对象

 *   7.判断容器中是否包含指定Person对象

 *   8.获取容器中Person的个数

 *   9.将容器变为数组,遍历所有的Person对象

 *   

 *  分析:

 *   1. Person类:

 *  1.属性: 姓名和年龄

 *  2.重写hashCode 和 equals方法

 *  2.1 如果不重写,调用Object类的equals方法,判断的是内存地址,必然是false;

 *  2.2 重写equals方法,判断条件为 name 和 age的值相等就认为 两个Person对象相等;

 *  2.3 如果两个对象相等,那么hashCode也要相同,需要重写hashCode方法

 *  2.4 重写toString方法, 直接调用Object类的toString方法,打印的是该对象的内存地址

 *  

 *  */

Person p1 = new Person("张三", 18 );

Person p2 = new Person("李四", 19 );

Person p3 = new Person("王五", 20 );


//增加

Collection<Person> lst = new ArrayList<Person>();

lst.add( p1 );

Collection<Person> lst2 = new ArrayList<Person>();

lst2.add(p2);

lst2.add(p3);

lst.addAll(lst2);

System.out.println( lst );

//删除

boolean rmv =lst.remove(p2);

System.out.println( "是否删除成功:"+rmv );

System.out.println( lst );

boolean rmv2 =lst.removeAll(lst2);

System.out.println( "是否删除成功:"+rmv2 );

System.out.println( lst);

//清空

lst.clear();

System.out.println(lst);

//判断集合是否为空

System.out.println( "集合是否为空:"+lst.isEmpty() );

//获取集合的长度

System.out.println( "集合的长度:"+lst.size() );


//判断集合中是否有指定的元素

System.out.println( "是否含有该元素:"+lst.contains(p1) );

//判断集合中是否有指定的元素子集

System.out.println( "是否含有该元素子集:"+lst.containsAll(lst) );

lst.addAll(lst2);

//for循环遍历 集合

for( Person person :lst2 ){

System.out.println(person );

}

//Iterable

Iterator<Person>  iterator = lst2.iterator();  //获取集合中的迭代器

while( iterator.hasNext() ){

Person person = iterator.next();

System.out.println(person );

}


  }

}



class Person {

private String name = "";

private int   age  = 0;

public Person(){}

public Person( String name, int age ){

this.name =name;

this.age  =age;

}

//1.重写hashCode

public int  hashcode(){

return  this.name.hashCode()+this.age;

}

//2.重写equals方法

public boolean equals( Objectobj ){

if( !(objinstanceof Person) ){//如果不是同一类型,返回false

returnfalse;

}

Person person = (Person)obj;

return person.name.equals(this.name) &&person.age==this.age;

}

//3.重写tostring方法

public String toString(){

return"Perosn { name="+name+", age="+age+"}";

}

}







LIST

/* |---Iterable 接口

*      Iterable    Iterator()

*      

*      |------  Collection接口

*        

*           |------ List  接口 ( 接口元素可以重复,允许在指定位置插入元素,并通过索引访问元素 )

* List集合特有方法

* 1. 增加

void add( int index, E element )  指定位置添加元素;  ( 没有insert,add( e)表示在末尾插入 )

boolean addAll( int index, Collection c )  指定位置添加集合,(子集中元素一个个遍历添加进集合)

* 继承的方法:

* void add( E e );

* viod addAll( Collection c );

* 2. 删除

* E remove( int index )  删除指定位置元素

* 继承的方法:

* Object  remove( int index );

* boolean removeAll( Collection c );

* 3. 修改

* E set( int index, E element )   返回的是需要替换的集合中的元素

* 4. 查找

* E get( int index )  

* int  indexOf( Object o )

* int  lastIndexOf( Object o )

* 5. 求子集合

* List<E>  subList( int  fromIndex, int toIndex )   //(startIndex, endIndex)

* */

ArrayList<String> list = new ArrayList<String>();

/*

 *    增加:

 *      add( E e );

 *      add( int loc, E e );

 *      addAll( Collection c );

 *      addAll( int loc, Collection c );

 * */

list.add("计算机网络");

list.add(0, "现代操作系统");

list.add(0, "java编程思想");

list.add(0, "java核心技术");

list.add(0,"java语言程序设计");

list.add(0, "舒克和贝塔");

System.out.println(list);

ArrayList<String> list2 = new ArrayList<String>();

list2.add("史记");

list2.add("资治通鉴");

list2.add("全球通史");

boolean addAll =list.addAll(list2);

System.out.println( addAll );

System.out.println( list );

/*  删除

* boolean remove( Object o );

* Object  remove( int index );

* boolean removeAll( Collection c );

* */

Object removeObject = list.remove(0);

Boolean remove  = list.remove("史记");

System.out.println( removeObject );

System.out.println( remove );

System.out.println( list );

list.removeAll(list2);


/*  修改

* Collection中没有修改API

* public E set(int index, E element) 

* */

Object set  = list.set(0, "编程");   //集合中原来的元素会被替换,并且将该元素返回

System.out.println(set);

System.out.println(list);

/*  查找

public E get(int index)   //根据index查找元素

public int indexOf(Object o)  //根据对象来查找index

*       public int lastIndexOf(Object o) //逆序查找index

* */

Object eObject = list.get( list.size()-1 );

System.out.println( eObject );

System.out.println( list );

int index =list.indexOf(eObject);

System.out.println( index );

index = list.lastIndexOf(eObject);

System.out.println( index );








/* ArrayList 

* |----  Iterable  (Iterator)

*     |----- Collection  接口

* |----- List   接口

* |----- ArrayList   底层采用数组实现,默认10.每次增长60%,(oldCapacity*3)/2+1; 查询快,增删慢;

* |----- LinkedList

*ArrayList: 实现原理:

* 数组实现,查找快,增删慢; ( 存储地址可以计算得出,所以查询快; 但是每次分配一整块地址,所以增删慢 ) 

*  

*  数组为什么查询快? 

-> 因为数组的内存空间地址是连续的,存储地址可以计算得出;

*  ArrayList的容量增长:

-> ArrayList底层维护了一个Object[]数组, 用于存储对象; 默认数组的长度是10。 可以通过new ArrayList(20)显式的指定

  用于存储对象的数组的长度; 当默认的或者指定的容量不够存储对象的时候,容量自动增长为原来的容量的1.5倍。

*  

*  ArrayList为什么增删慢?

-> 由于ArrayList是数组实现,在增和删的时候会牵扯到数组增容,以及拷贝元素,所以慢。数组是可以直接按索引查找,所以查找快。

  但是增删的时候,元素需要整体移动,且还可能有增容问题,所以增删的效率较低;

*  

*  

*  

*  

*  

*  

*  

*  

*  

* LinkedList

* LinkedList: 链表实现,增删快,查找慢;

*   由于LinkedList在内存中地址不连续,需要让上一个元素记住下一个元素的地址,所以每个元素中保存的有下一个元素的位置。虽然也有角标,

* 但是查找的时候,需要从头往下找,显然是没有数组查找快; 但是,链表在插入新元素的时候,只需要让前一个元素记住新元素,让新元素记住下

* 一个元素就可以了,所以增删快;

* LinkedList 经常模拟 队列,栈的使用,所以有一些特有的方法 

addFirst( E e );

addLast( E e );

getFirst(  );

getLast();

removeFirst();

removeLast();

*  

*  数据结构:

1. 栈

先进后出

push();  //进栈

pop();   //出栈

*  

2. 队列

先进先出

offer()

poll();

*  

*  返回逆序的迭代器对象

descendingIterator()  //返回逆序的迭代器对象

* */  

LinkedList<String> list = new LinkedList<String>();

list.add("西游记");

list.add(0, "三国演义");

list.add(0,"石头记");

list.add(0, "水浒传");

list.addFirst("史记");

list.addLast("呐喊");

System.out.println( list );

 

/* 获取  

  *  Object get(int index);

  *  Object getFirst();

  *  Object getLast();

  *  */

String string = ( String )list.get(0);

System.out.println( string );

string = list.getFirst();

System.out.println( string );

string = list.get(list.size()-1);

System.out.println( string );

string = list.getLast();

System.out.println( string );

 

 

/* list大小 */

System.out.println( list.size() );

 

/* 迭代 */

Iterator<String> iterator = list.iterator();

System.out.println( );

System.out.print("[" );

while( iterator.hasNext() ){

 

String string2 = (String)iterator.next();

System.out.print(string2+", " );

}

System.out.println("]" );

 

 

 

 

 

 

 

 

 

/* LinkedList 模拟堆栈的先进先出 */

list.clear();

 

/* 进栈 */

list.push("西游记");

list.push("三国演义");

list.push("石头记");

list.push("水浒传");

System.out.println( list );

 

/* 出栈 */

String string3 = list.pop();

System.out.println( string3 );

string3 = list.pop();

System.out.println(string3);

string3 = list.pop();

System.out.println(string3);

 

 

 

/* LinkedList 模拟队列的先进先出

  * ...

  *  */

 

 

 

/* ArrayList 和 LinkedList的存储查找的优缺点:

  * 

  * 1.ArrayList 是采用动态数组来存储元素的,它允许直接使用index来查找元素; 但是增删元素涉及到整体的移动; 

  * 

  * 2.LinkedList 是采用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可;所以插入

  *  速度快;

  *  

  * */

 

 

 

 

 

 

 

/* Vector

  *  

  * Vector : 描述的是一个线程安全的ArrayList;

  * ArrayList: 单线程效率高; Vector:多线程安全,效率低; 

  * 

  * 特有方法:

  * void addElement( E obj )  //在集合末尾添加元素

  * E    elementAt( int index ) //返回制定index的元素

  *     Enumeration  elements()    //返回集合的迭代器对象

  *     

  * Enumeration 接口:

  * boolean hasMoreElements()  //测试此枚举是否包含更多的元素

  * E  nextElement() //如果此枚举对象至少还有一个可提供的元素,就返回此枚举的下一个元素; 否则,抛出异常;    

  *     

  * */

Vector<String> vector = new Vector<String>();

vector.addElement("111"); //添加到集合末尾

vector.addElement("2222"); 

 

String string4 = vector.elementAt(0);

System.out.println( string4 );


//遍历Vector

Enumeration<String> ens = vector.elements();

while( ens.hasMoreElements() ){

 

System.out.println(ens.nextElement() );

}


0 0
原创粉丝点击