java 集合类学习笔记

时间:2022-02-12 17:00:02

        引入集合类的原因:java数组是固定长度的,数组在创建的时候就指定了长度,在一些情况下长度并不是一定的,这时就需要用集合来进行数据存储。使用集合还可以在其中放对象的引用,但不能存放基本数据类型。

集合分类:Set(集合):集合中对象不按特定的方式排序,并且没有重复对象,但它有些实现类中的对象按特定方式排序。

List(列表):集合中的对象按检索位置排序,可以有重复对象,允许按照对象在集中的索引位置检索对象,和数组类似。

Map(映射):集合的每一个元素包含一对键对象和值对象,集合中没有重复的键对现象,值对象可以重复,它的有些实现类能对集合中的键对象进行排序。

 java 集合类学习笔记

1. List和Set继承自Collection接口

2. 排序的操作接口:SortedMap、SortedSet

3. 输出的操作接口:Iterator、ListIterator、Enumeration

Collection定义了如下方法:

1

Public boolean add(E e)

普通

向集合中增加元素

2

boolean addAll(Collection<? extends E> c)

普通

向集合中加入一组数据

3

void clear()

普通

清空所有内容

4

boolean contains(Object o)

普通

判断是否有制定内容,查找

5

boolean equals(Object o)

普通

对象比较

6

int hashCode()

普通

返回hash码

7

boolean isEmpty()

普通

判断集合内容是否为空

8

Iterator<E> iterator()

重要

为Iterator接口实例化,迭代输出

9

boolean remove(Object o)

普通

从数组中删除指定对象

10

boolean retainAll(Collection<?> c)

普通

 

11

int size()

普通

取得数组大小

12

Object[] toArray()

 

取得全部内容,以数组形式返回

13

<T> T[] toArray(T[] a)

 

取得全部内容

Collection接口的iterator()和toArray()方法都可以获得集合中的所有元素,前者返回Iterator对象,后者返回一个包含集合中所有元素的数组。

Iterator隐藏底层集合的数据结构,向客户程序提供了遍历各种类型的集合的统一接口。

Iterator接口中声明了如下方法:  hasNext():判断集合中的元素是否遍历完毕,如果没有,就返回true。  next():返回下一个元素  remove():从集合中删除上一个由next()方法返回的元素。

如果集合中的元素没有排序,Iterator遍历集合中元素的顺序是任意的,并不一定与像集合中加入的元素的顺序一致。

Set:

Set是最简单的一种集合,集合中的对象不按特定方式排序,并没有重复对象。Set接口主要有两个实现类:HashSet类还有一个子类LinkedHashSet类,它不仅实现了哈希算法,而且实现了链表数据结构,链表数据结构能提高插入核算出元素的性能。TreeSet类实现了SortedSet接口中,具有排序功能。

List:

List的主要特征是先创建就先存储,集合中允许存放重复对象。List接口主要的实现类包括:ArrayList—ArrayList代表长度可变的数组。允许对元素进行快速的随机访问,但是向ArrayList中插入与删除元素的速度较慢。LinkedList—在实现中采用链表数据结构。对顺序访问进行了优化,向List中插入和删除元素的速度较快,随机访问速度则相对较慢,随机访问是指检索位于特定索引位置元素。

Map:

Map(映射)是一种把键对和值对象进行映射的集合。它的每一个元素都包含一对键对象和值对象,而之对象仍可以是Map类型。 以此类推,这样就形成了多级映射。向Map集合中加入元素时,必须提供一对键对象和值对象,从Map集合上检索元素只要给出键对象,就会返回值对象。

Set接口:

1. HashSet类:

HashSet按照哈希算法—存取集合中的对象,具有很好的存取和查找功能。当向集合中加入对象,调用hashCode()方法来多出hash码,根据hash码计算对象在集合中的存放位置。

public class HashSetDemo {

 

/**

 * @param args

 * 无序的  不能添加重复元素

 * Object类中的hashCode()和equals()方法完成重复元素的验证

 * 一个完整的类必须覆写Object类中的hashCode和equals方法

 */

public static void main(String[] args) {

// TODO Auto-generated method stub

             Set allSet=new HashSet();

             allSet.add("hehe");

             allSet.add("haha");

             allSet.add("Hello!!");//增加相同的元素

             allSet.add("Hello!!");//增加相同的元素

             allSet.add("Hello!!");//增加相同的元素

             allSet.add("World!!");

             System.out.println(allSet);

             

             Set<Person1> allSet1=new HashSet<Person1>();

             allSet1.add(new Person1("张三",78));

             allSet1.add(new Person1("赵六",23));

             allSet1.add(new Person1("王五",14));

             allSet1.add(new Person1("李四",56));

             allSet1.add(new Person1("陈八",9));//增加相同的元素

             allSet1.add(new Person1("陈八",9)); //年龄相同 默认会认为是同一个对象,要改正这一现象需要在compareTo中 return 0更改

//实现同步

//Set s = Collections.synchronizedSet(new HashSet(...));

             System.out.println(allSet1);

}

 

}

class Person1 implements Comparable<Person1>{    //实现comparable接口进行比较

private String name;

private int age;

public Person1(String name, int age) {

super();

this.name = name;

this.age = age;

}

public String toString(){

return "姓名:"+this.name+";年龄:"+this.age;

}

@Override

public boolean equals(Object obj) {

// TODO Auto-generated method stub

if(this==obj){

return true;

}

if(!(obj instanceof Person1)){

return false;

}

Person1 p=(Person1)obj;

if(this.name.equals(p.name)&&this.age==p.age){

return true;

}else {

return false;

}

}

public int hashCode(){ //这个方法的返回值都是通过一个公式计算的

//此时的公式:名字的hashcode * age

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

}

@Override

public int compareTo(Person1 o) {

// TODO Auto-generated method stub

if(this.age>o.age){

return 1;

}else if(this.age<o.age){

return -1;

}else{

//return 0;

return this.name.compareTo(o.name);

}

}

}

2. TreeSet类:

能够对集合中的对象进行排序

3. public class TreeSetDemo {

4. 

5.  /**

6.   * @param args

7.   * 可以排序的 不允许重复

8.   * 一个自定义的类本身不知道该如何排序   对象所在的类必须实现Comparable接口,并覆写compareTo()方法

9.   */

10.  public static void main(String[] args) {

11.  // TODO Auto-generated method stub

12.  Set<Person> allSet=new TreeSet<Person>();

13.         allSet.add(new Person("张三",78));

14.         allSet.add(new Person("赵六",23));

15.         allSet.add(new Person("王五",14));

16.         allSet.add(new Person("李四",56));

17.         allSet.add(new Person("孙七",9));//增加相同的元素

18.         allSet.add(new Person("陈八",9)); //年龄相同 默认会认为是同一个对象,要改正这一现象需要在compareTo中return 0更改

19.         System.out.println(allSet);

20.  }

21. 

22. }

23. class Person implements Comparable<Person>{

24.  private String name;

25.  private int age;

26.  public Person(String name, int age) {

27.  super();

28.  this.name = name;

29.  this.age = age;

30.  }

31.  public String toString(){

32.  return "姓名:"+this.name+";年龄:"+this.age;

33.  }

34.  @Override

35.  public int compareTo(Person o) {

36.  // TODO Auto-generated method stub

37.  if(this.age>o.age){

38.  return 1;

39.  }else if(this.age<o.age){

40.  return -1;

41.  }else{

42.  //return 0;

43.  return this.name.compareTo(o.name);

44.  }

45.  }

46. 

47. } 

List接口:最大的特点是里面的内容都可以重复。

1

Public void add(int index,E element)

普通

在指定位置处加入元素

2

Public Boolean addAll(int index ,Collection<?extends E>c)

普通

在指定位置增加一组元素

3

Public E get(int index)

普通

通过索引位置可以取出每一个元素

4

Public E remove(int index)

普通

删除指定位置内容

5

Public E set(int index,E element)

普通

修改指定位置内容

6

Public List<E> subList(int fromIndex,int toIndex)

普通

截取子集合

7

Public int lastIndexOf(Object o)

普通

返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1

8

Public int indexOf(Object o)

普通

回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1

9

ListIterator<E>  listIterator()

普通

返回此列表元素的列表迭代器(按适当顺序)

 

4.ArrayList类:

长度可变的数组,允许所有对元素进行快速随机访问,允许有null,ArrayList线程不同步,向ArrayList中插入和删除元素速度较慢。

ListIterator只有在List集合中有,才可以使用进行迭代。

hasPrevious()如果以逆向遍历列表,列表迭代器有多个元素,则返回 true

previous() 返回列表中的前一个元素

set(E e) 用指定元素替换 next 或 previous 返回的最后一个元素(可选操作)

public class ArrayListDemo1 {

 

/**

 * @param args

 */

public static void main(String[] args) {

// TODO Auto-generated method stub

         List  allList=new ArrayList(); 

         allList.add("hello");  //增加元素,Collection接口定义

         allList.add(0, "hehe");//增加元素,List接口定义

         allList.add("world");//增加元素,Collection接口定义

         allList.add(3);

         allList.add(5);

         System.out.println(allList);

         

         allList.remove(2);

         //allList.remove("hehe");  //删除对象元素

         System.out.println(allList);

         for(int i=0;i<allList.size();i++)

         {

          System.out.println(allList.get(i));

         }System.out.println("***************");

         

         List  allList1=new ArrayList(); 

         allList1.add("hello");  //增加元素,Collection接口定义

         allList1.add("hehe");//增加元素,Collection接口定义

         allList1.add("world");//增加元素,Collection接口定义

         allList1.add("hehe");

         allList1.add(3);

         allList1.add(5);

         System.out.println(allList1);

         

         allList1.remove("world");

         //allList.remove("hehe");  //删除对象元素

         System.out.println(allList1);

         

         Object obj[] =allList1.toArray();  // 按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。

       

         for(int i=0;i<obj.length;i++) 

         {

          System.out.println(obj[i]);

         }

         System.out.println("判断某个字段是否存在:"+allList.contains("world")); 

         System.out.println("得到元素第一次出现的位置"+allList1.indexOf("hehe"));

         System.out.println("得到元素最后一次出现的位置"+allList1.lastIndexOf("hehe"));

         System.out.println("查询其中第几条到第几条的数据:"+allList.subList(0,3 ));//下标从0到2的数据取出,而不包含3

         ListIterator<String> iter=allList1.listIterator();  //ListIterator只有List集合中有  

         while(iter.hasNext()){

          Object str=iter.next();

          System.out.println(str);

         }

         while(iter.hasPrevious())

         {

         //要想执行由后向前的操作,必须先执行由前向后的操作!!

           //可以直接进行修改

          System.out.println("从后向前输出:"+(Object)iter.previous()+"、");

         

         }

}

 

}

4. LinkedList类:

LinkedList实现了List接口,允许null元素,在实现中采用链表数据结构。对顺序访问进行了优化,向List中插入和删除元素速度快,随机访问速度相对较慢,随机访问是指检索位于特定索引位置的元素。

LinkedList没有同步方法,如果多个线程同时访问一个List,则必须实现访问同步。

一种解决方式是创建List时构造一个同步的List:

List list=Collection.synchronizedList(new List(…));

public class LinkedListDemo1{

 

/**

 * @param args

 * LinekedList可以进行向前和向后查询表,但前提是先向后进行扫,而后才可以用向前扫的方式

 */

public static void main(String[] args) {

// TODO Auto-generated method stub

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

            link.add("hehe");

            link.add("haha");

            link.addFirst("我了个去!!");

            link.addLast("你了个去哪??");

            for(int i=0;i<link.size();i++)

            {

//             System.out.println(link.get(i));

             System.out.print(link.element());    //取出表头循环输出

            }

            System.out.println("\n通过element操作之后"+link);

            for(int i=0;i<link.size();i++)

            {

             System.out.print(link.poll());    //取出表头同时删除表头

            }

            System.out.println("\n通过poll操作之后"+link);

            //System.out.println("取出链表头:"+link.getFirst());

            //System.out.println("取出链表尾:"+link.getLast());

       }

}

}

}

Map接口:

Map(映射)是一种把键对象和值对象进行映射的集合,它的每一个元素都包含一对键对象和值对象,而值对象仍可以是Map类型。这样可以形成多级映射。

HashMap类:

按照哈希算法存取Map中的对象,允许存储为空,而且键是空。

public class HashMapDemo {

 

/**

 * @param args

 */

private static Random rand=new Random();

public static void main(String[] args) {

// TODO Auto-generated method stub

Map hm=new HashMap(); 

  for(int i=0;i<1000;i+=1){ 

      Integer r=new Integer(rand.nextInt(20)); 

      if(hm.containsKey(r)) 

      ((Counter)hm.get(r)).i++; 

      else 

      hm.put(r,new Counter()); 

     } 

     System.out.println(hm); 

}

 

}

class Counter{ 

 int i=1; 

 public String toString(){ 

  return Integer.toString(i); 

 } 

}

HashTable类:

Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可以作为key或者value。

public class HashTableDemo {

 

/**

 * Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可以作为key或者value。

 * @param args

 */

public static void main(String[] args) {

// TODO Auto-generated method stub

String names[]={"张三","李四","王五","赵六","陈七","孙九"}; 

  float diameters[]={4800f,12103.6f,12756.3f,6794f,142984f,120536f}; 

  Hashtable hash=new Hashtable(); 

  for(int i=0,n=names.length;i<n;i++){ 

   hash.put(names[i],new Float(diameters[i])); 

  } 

  Enumeration e=hash.keys(); //返回此哈希表中的键的枚举

  Object obj; 

  while(e.hasMoreElements()){   

  obj=e.nextElement(); 

  System.out.println(obj+":"+hash.get(obj)); 

  }

  

}

 

}

HashMap和HashTable的区别:

HashTable继承自Dictionary,而HashMap是Map接口的一个实现 HashMap允许将null作为一个key或者value,而HashTable不允许。HashMap把HashTable的contains方法去掉了,才成containsvalue和containsKey。 最大的不同是,HashTable的方法是synchronize的,而HashMap不是,在多个线程访问HashTable时,不需要自己为它的方法实现同步而HashMap就必须为之提供外同步。

ArrayList和Vector的区别:

ArrayList与Vector都是java中集合类,区别:

同步性:Vector是同步的,这个类中的一些方法保证了Vector中的对象时线程安全的,ArrayList是异步的,同步的要求会影响执行的效率,如果对安全性要求不是那么高,使用ArrayList是很好的选择,可以避免同步带来的不必要的性能开销。

数据增长:从内部实现机制来讲,ArrayList和Vector都是使用数组(Array)来控制集合中的对象,当在添加数目的时候,如果超过内部数组的长度,在扩展内部数组长度时,Vector缺省情况下自动增长为一倍的数组长度,ArrayList增长原来的50%,要想保存大量数据,Vector更有优势。

集合选取的一般方式:

如果线程安全:使用Vector、HashTable

如果不要求线程安全:ArrayList LinkedList HashMap

要求使用键值对:HashMap HashTable

大数据量又考虑线程安全,使用Vector。