java_集合框架

集合框架

 集合和数组的区别:

 

集合

数组

长度

可变的

固定的

存储的对象

可以存储不同类型的对象(只能存对象)

只能存同一种对象、可以存储基本数据类型

都是容器


为什么会出现这么多的容器呢?

因为每一个容器存储数据的方式都不同。存储方式就叫做数据结构。


Collection中的共性方法:

add();添加元素。

addAll(Collection c);添加一组元素,将另一个容器的元素全添加进来。

clear();清空容器。

contains();判断容器中是否包含某元素,返回值为boolean

isEmpty();判断容器是否为空。返回boolean

remove();移除容器中的某元素。

removeAll(Collection c);移除容器中和c容器的交集。改变原容器元素,并不是返回新容器。

retainAll(Collection c);保留容器中和c容器的交集。改变原容器元素,并不是返回新容器。

size();获取容器的长度。

集合容器中存储的是对象的地址,不是实体。

对集合容器中元素的取出用迭代器:

ArrayList al = new ArrayList();//定义一个集合,并添加两个元素。

al.add("heima01");

al.add("heima02");

Iterator it = al.iterator();//al.iterator返回的是一个对象,并被Iterator接口引用

while(it.hasNext()){

         //it.hasNext是通过hasNext方法来判断所指对象中的元素是否存在,存在则返回true

System.out.println(it.next());//it.next则是取出存在的元素。

}

List集合与Set集合的异同:

 List:元素是有序的,元素可以重复,元素有索引。可以操作脚标的就是List

Set:元素是无序的,元素不可以重复。

List集合的特有方法:

1add(index,element):在脚标index处添加element元素。

 2addAll(index,Collection):在脚标index处添加一组元素。

 3remove(index):删除index脚标处的元素。

4set(index,element):修改index脚标处的元素,改成element

 5get(index):获取index脚标处的元素。

6subList(from,to):获取从from脚标到to脚标的元素,包含头不含尾。

 7listIterator():迭代器。

在用Iterator迭代器迭代时,不可以通过集合对象的方法操作集合中的元素,也就是说,不可以一边迭代一边用集合对象方法操作元素,包含添加、修改等操作,可以用Iteratorremove方法移除操作。要不然的话,会发生ConcurrentModificationException异常。

要想一边迭代,一边作添加,修改等操作,就用ListIterator。其方法是Iterator的子接口,方法比Iterator多,其中有:

hasPrevious():返向遍历,和hasNext()相反。

previous():返回列表中前一个元素,和next()相反。

remove():移除当前迭代到的元素。

set():修改当前迭代到的元素。

List集合的三个小弟的特点:

1ArrayList:数组结构。特点:查询速度快,增删稍慢。线程不同步。1.2版本出现的。

 2LinkedList:链表结构。特点:查询速度慢,增删快。

3Vector:数组结构。无论增删查询都慢。和ArrayList的功能一样,不同之处是线程同步,1.0版本就有了。被ArrayList替代了,遇到多线程,自己加锁。

Vector中特有的取出方式:枚举

1、枚举和迭代器是一样的。

2、枚举被失代器取代了。

LinkedList的特有方法:

offerFirst():添加元素到起始位置。   **1.6版本以前是:addFirst()

offerLast()添加元素到末尾位置。   **1.6版本以前是:addLast()

peekFirst()获取起始位置的元素,不删除,如果没有元素,返回null   **1.6版本以前是:getFisrt()

peekLast()获取末尾位置的元素,不删除,如果没有元素,返回null   **1.6版本以前是:getLast()

pollFirst():获取起始位置的元素,同时删除,如果没有元素,返回null    **1.6版本以前是:removeFirst()

pollLast():获取末尾位置的元素,同时删除,如果没有元素,返回null    **1.6版本以前是:removeLast()

练习:除集合中的重复自定义元素

/*

去除集合中的重复的自定义元素。

*/

import java.util.ArrayList;

import java.util.Iterator;

 

public class LinkedTest_03 {

public static void main(String[] args) {

 ArrayList al = new ArrayList(); //定义ArrayList集合

 //al集合中存入Person元素,其中有相同的元素。

 al.add(new Person("樊波",28));    

al.add(new Person("樊波",28));

 al.add(new Person("向波",27));

 al.add(new Person("樊波",28));

al.add(new Person("张明照",40));

al.add(new Person("黄权",29));

 al.add(new Person("黄权",29));

al.add(new Person("向波",27));

al.add(new Person("罗练",25));    

 al = xiaoChong(al);  //al消重。 

      //打印消重后的al元素。

 Iterator it = al.iterator();

 while(it.hasNext()){

Person p = (Person)it.next();

System.out.println("姓名:"+p.getName()+"    "+"年龄:"+p.getAge());

 }    

}

      //消重方法。

 publicstatic ArrayList xiaoChong(ArrayList arr){

 ArrayList newal = new ArrayList();

 Iterator it = arr.iterator();

 while(it.hasNext()){

 Object obj = it.next();

//判断参数集合的元素,是否在新集合中存在,不存在,则存入新集合中。

 if(!newal.contains(obj))

 newal.add(obj);

 }

 return newal;//返回消重后的新集合。

}    

}

//自定义Person类,并写覆写Object中的equals方法,实现自己的比较方式。姓名和年龄都相同,则为同一个人。

class Person{

private Stringname;

private int age;

Person(String name,int age){

 this.name = name;

this.age = age;

   }

public String getName(){

 returnname;

   }

 publicint getAge(){

return age;

   }

   publicboolean equals(Object obj){

      if(!(objinstanceof Person))

          returnfalse;

      Person p = (Person)obj;    

      returnthis.name.equals(p.name) &&this.age==p.age;

   }

}

注:contains和remove底层用的都是equals。

在开发中,如果存储的元素较多,涉及到增删比较多,用LinkeList,如果对存储的数据查询比较频繁,用ArrayListArrayList在开发中用得最多。

HashSet

HashSet是如何保证元素的唯一性的呢?

是通过元素的两个方法,hashCodeequals来完成。

如果元素的HashCode值相同,才判断equals是否为true

如果元素的hashCode值不同,不会调用equals

注意:

HashSet判断元素是否存在,以及删除等操作,先依赖hasCode,再依赖equals方法。

ArrayList判断元素是否存在,只依赖equals方法。

TreeSet

可以对Set集合中的元素进行排序。往TreeSet集合存对象,这个对象必须具备比较性。

练习:TreeSet存储自定义对象,并用指定方式排序。

import java.util.Iterator;

import java.util.TreeSet;

 

public class TreeSetTest {

 publicstatic void main(String[] args) {

TreeSet ts = new TreeSet();//创建TreeSet集合

       //向集合中添加Student对象,其中有相同元素。

      ts.add(new Student("樊波",25));

      ts.add(new Student("向波",24));

      ts.add(new Student("b",21));

      ts.add(new Student("a",20));

      ts.add(new Student("樊波",25));

      //迭代打印出Student对象的属性。

      Iterator it = ts.iterator();

      while(it.hasNext()){

         Student p = (Student)it.next();

         System.out.println(p.getName()+"  "+p.getAge());

      }

   }

}

//创建Student类,并实现Comparable接口,并覆盖compareTo方法,方法中定义自定义的比较方式,先按性名排序,再按年龄排。

class Studentimplements Comparable{

   private Stringname;

   privateint age;  

   Student(String name, int age){

      this.name = name;

      this.age = age;

  

   public String getName(){

      returnname;

  

 publicint getAge(){

      returnage;

  

   public int compareTo(Object obj){

      if(!(objinstanceof Student))

         thrownew RuntimeException("不是人这个对象");   

      Student p = (Student)obj;

      if((this.name.compareTo(p.name))>0)

         return 1;

      if(this.name.compareTo(p.name)==0){

         if(this.age>p.age)

            return 1;

         if(this.age<p.age)

            return -1;

         return 0;

      }       

      return -1;

   }

}

Map集合

存储键值对,一对一对的存,而且要保证键的唯一性。

键不可以重复,值可以重复。存值的时候,如果重复了键,那么第二次存的键值覆盖前一次存的键值。

       其共性方法:

       1、添加:

              put(key,value):一对一对存储。如果添加时,相同的键,那么后添加的值会覆盖原有键对应的值,并put方法会返回被覆盖的值。

              putAll():一次存一堆。

       2、删除:

              clear():清空。

              remove(key):通过键来删除元素。

       3、判断:

              containsValue(value)

              containsKey(key)

              isEmpty():是否为空。

       4、获取:

              get(key):通过键获取元素。可以通过get方的的返回值来判断一个键是否存在,通过返回null来判断。

              size()

              values():返回的是一个Collection集合,获取Map里面的所有值。

       keySet()map中的所有的键取出存到Set集合中,Set集合具备迭代器,所以可通过过迭代取出所有的键,再根据get方法,获取每个键对应的值。

       例如:

package CollectionTest;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Set;

 

public class MapTest {

   publicstatic void main(String[] args) {

      //定义一个Map集合。

      Map<String,String> map = new HashMap<String,String>();

      //向集合中存入5个键值对元素。

      map.put("fan01", "fan  bo1");

      map.put("fan02", "fan  bo2");

      map.put("fan04", "fan  bo4");

      map.put("fan03", "fan  bo3");

      map.put("fan05", null);

      //keySet方法将Map集合中的键取出来,并存入到Set集合中。

      Set<String> set = map.keySet();

      //迭代取出Set集合中的Ket,并用get方法获得键对应的值。

      Iterator<String> it = set.iterator();

      while(it.hasNext()){

         String str = it.next();

         System.out.println("Key:"+str+"  Value:"+map.get(str));

      }    

entrySet()

返回的类型为:Set<Map.Entry<k,v>>返回的是Set集合,类型为Map.Entry<k,v>

Map集合中的映射关系存入到Set集合中,而这个关系的数据类型就是:Map.Entry。存入到Set集合了,就可以用迭代器了。

例如:

public class MapTest {

   public static void main(String[]args) {

      //定义一个Map集合。

      Map<String,String> map =new HashMap<String,String>();

      //向集合中存入5个键值对元素。

      map.put("fan01", "fan  bo1");

      map.put("fan02", "fan  bo2");

      map.put("fan04", "fan  bo4");

      map.put("fan03", "fan  bo3");

      map.put("fan05", null);

      //通过entrySet方法将Map集合的键值关系存入到Set集合中。

      Set<Map.Entry<String,String>>set = map.entrySet();

      //迭代取出Set集合中的关系元素。

      Iterator<Map.Entry<String,String>> it = set.iterator();

      while(it.hasNext()){

         Map.Entry<String,String>me = it.next();

         //再通过getKeygetValue方法获得Map里面的键和值。

         Stringkey = me.getKey();

         Stringvalue = me.getValue();

         System.out.println("Key:"+key+"  Value:"+value);

      }

}

}

Hashtable:底层是哈希表数据结构,不可以存入null键和null值,线程同步的,效率低。

HashMap:底层是哈希表数据结构,允许使用null键和null值,线程不同步的,效率高。

TreeMap:底层是二叉树数据结构,线程不同步,可以用于给Map集合中的键进行排序。

Map集合和Set集合很像,Set底层就是用了Map集合。

Map里面没有迭代器。

练习:

/*

 * 自定义一个SuperPerson类,并将此类作为键,地址作为值,存入HashMap中。

 * 定义SuperPerson类时,让元素具备可比性。

 * */

package CollectionTest;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Set;

import java.util.TreeMap;

 

public class HashMapTest {

   public static void main(String[] args) {

      //定义TreeMap集合,并将SuperPerson作为键,地址作为值。

      TreeMap<SuperPerson,String> tm = newTreeMap<SuperPerson,String>();

      //TreeMap集合中存入元素。

      tm.put(new SuperPerson("fanbo",25),"月波");

      tm.put(new SuperPerson("xianbo",20),"越溪");

      tm.put(new SuperPerson("huangquan",14),"商州");

      tm.put(new SuperPerson("zhouyifei",28),"北京");

      tm.put(new SuperPerson("heweichao",25),"湖南");

      tm.put(new SuperPerson("heweichao",25),"湖南");

      /*

      //第一种取出方式:keySet()

      Set<SuperPerson> set = hm.keySet();

      Iterator<SuperPerson> it = set.iterator();

      while(it.hasNext()){

         SuperPerson sp = it.next();

         String value = hm.get(sp);

         System.out.println(sp.getName()+"  "+sp.getAge()+"   "+value);      

      }

      */

      //第二种取出方式:entrySet()

      Set<Map.Entry<SuperPerson,String>> me =tm.entrySet();

      Iterator<Map.Entry<SuperPerson,String>> iter =me.iterator();

      while(iter.hasNext()){

         Map.Entry<SuperPerson, String> ME = iter.next();

         SuperPerson SP = ME.getKey();

         String VALUE = ME.getValue();

         System.out.println(SP.getName()+"  "+SP.getAge()+"  "+VALUE);

      }

   }

}

//定义SuperPerson类,并实现Comparable接口。

class SuperPersonimplements Comparable<SuperPerson>{

   private Stringname;

   private int age;

   SuperPerson(String name,int age){

      this.name = name;

      this.age = age;

   }

   public String getName(){

      return name;

   }

   public int getAge(){

      return age;

   }

   //覆盖hashCode()方法。

   public int hashCode(){

      return name.hashCode()+age*33;

   }

   //覆盖equals方法。

   public boolean equals(Object obj){

      if(!(objinstanceof SuperPerson))

         throw new RuntimeException("对象存错了。");

      SuperPerson sp = (SuperPerson)obj;

      return this.name.equals(sp.getName()) &&this.age == sp.getAge();

   }

   //覆盖Comparable接口中的compareTo方法。

   public int compareTo(SuperPerson sp1){

      int num =this.age-sp1.getAge();

      if(num == 0)

         return this.name.compareTo(sp1.getName());

      return num;

   }

}

集合框架工具类:

    Collections里面的方法全静态的。对集合进行操作。

      sort(List<T>list):对list集合进行排序。它不能给Set排序。

       sort(List<T>list,Comparator c):可以传入自定义比较器,按指定的规则进行比较

       max(List<T>list):获取一堆元素中的最大元素

max(List<T> list, Comparator c):获取按指定顺序排序后的最大元素。

      binarySearch(List<T>lT):二分法查找集合中的某元素,但凡用此方法,必须是有序集合。返回的是T元素的脚标,如果T不存在,则返回T应该在集合中的脚标的负数-1

fill(List<T> list,T):将集合中的所有元素全替换T元素。

replaceAll(List<T> list,T1,T2)T2元素替换T1元素.

reverse(List<T> list):反转。将集合中所有元素反转一下。

SynList()

reverseOrder():返回的是一个比较器,传入此比较器后,强行逆转集合中的元素。

reverseOrder(Comparable c):返回的还是一个比较器,比较器里再传入一个比较器,就是按参数比较之后,再强行逆转元素。

synchronizedCollection(Collection<T> c):传入一个不同步的集合,返回一个同步的集合。

swap(List<T> list,int i,int j):无返回值,将集合中脚标为ij的元素交换位置

shuffle(List<T> list):无返回值,随机的对集合中元素进行置换。(扑克牌)

示例:

Collections.sort(list);//排序,返回排序后的集合。     

Collections.sort(list,newMyComp());//传入自定义比较器,自定义排序。

String str = Collections.max(list);//获取集合元素中的最大值,返回元素。

String str = Collections.max(list,new MyComp());//获取指定排序后的最大元素,反回元素。

      int i =Collections.binarySearch(list,"cfjas");//返回指定元素在集合中的脚标。

Collections.fill(list,"ttttt");//list中的所有元素,替换成“tttt”

Collections.replaceAll(list,"aajs", "fanbo");//aajs替换成fanbo

Collections.reverse(list);//反转集合中的元素。

 Collections.sort(list,Collections.reverseOrder());//强行逆转集合中元素的比较器。

   Collections.swap(list, 2, 3);//23位置的元素交换一下位置。

   Collections.shuffle(list);//将集合中的元素随机的置换位置。

Arrays

       用于操作数组的工具类。里面也全是静态方法。

       asList(Array[]arr):将数组变成List集合。好处:可以使用集合的思想和方法,来操作数组中的元素。

注意:将数组变成集合,不可以使用集合的增删方法,因为数组的长度是固定的。可以使用containsgetindexOfsubList等等方法,如果增删,会发生不支持异常。

如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素。如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。

   Arrays中还有binarySearchcopyOfdeepToStringequalsfillsorttoString等等方法。

集合变成数组:

       toArray()

       toArray(T[]a):返回T类型的数组。

1、集合是可变长度的,数组是固定长度的,集合变成数组,得定义多大长度数组呢?

当指定类型的数组长度小于集合的size时,那么该方法内部会创建一个新的数组,长度为集合的size

       当指定类型的数组长度大于集合的size时,就不会新创建数组了,而是使用传递进来的数组。

所以创建一个刚刚好的数组最优。如:String[] arr = list.toArray(new String[list.size])

2、为什么要将集合变成数组?

为了限定对元素的操作,不需要进行增删了。




 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值