JAVA集合

首先需要清楚JDK类库给我们提供了Java集合,所有的Java集合都位于java.unti包中。与Java数组不同,Java集合不能存放基本类型数据,而只能存放对象的引用。
一、了解集合框架
1.1集合概念
集合有时称为容器,是一个包含很多元素的对象。集合可用来存储,检索和操作数据。
1.2集合框架
集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。所有的集合框架包含:接口、实现以及算法。
二、接口与实现
集合接口封装了不同的,collection接口是集合框架的基础,如图:
这里写图片描述

Set是一种特殊的Collection,SortedSet又是一种特殊的Set,Map不属于Collection。所有的Collection接口都是支持泛型的。

public interface Collection<T>,但是当要定义一个Collection实例的时候,需引入指定在该集合中包含的对象的类型。这可让编译器在编译时明确放入该集合的元素是那种类型的,减少了运行时错误的发生。

在理解了怎样使用这些接口后,也就理解了Java集合的框架,会根据实际情况选择哪一种集合接口。
下面简单介绍一下集合接口。
Collection接口是一组允许重复的对象。
Set接口继承Collection,但不允许重复,使用自己内部的一个排列机制。
List接口继承Collection,允许重复,以元素安插的次序来放置元素,不会重新排列。
Map接口是一组成对的键—值对象,即所持有的是key_value pairs.Map中不能有重复的Key。
三,接口中的方法
3.1 Collection接口
Collection接口用于表示任何对象或元素组。想要尽可能以常规方式处理一组元素时,就使用此接口,可以把集合转换成任何其他的对象组。但是,不能直接把集合转换成基本数据类型的数组,因为集合必须持有对象。

1.单元素的添加、删除操作
boolean add(Object o):将对象添加给集合;
boolean remove(Object o):如果集合中有与o相匹配的对象,则删除对象o;
2.查询操作
int size():返回当前集合中元素的个数
boolean isEmpty();
boolean contains(Object o):查找集合中是否有对象o
Iterator iterator():返回一个迭代器,用来访问集合中各个元素
3.组操作
boolean containsAll(Collection c):查找集合中是否含有集合c中的所有元素
boolean addAll(Collection c):将集合c中所有元素添加到该集合
void RemoveAll(Collection c):删除
void retainAll(Collection c):从集合中删除集合c不包含的元素
4.遍历集合
两种方式:
(1)通过for_each结构
for(Object o:collection){
System.out.println(o);
}
(2)使用迭代器
迭代器是一种能遍历集合并且能从集合删除元素的对象。可以通过调用Collection接口中的Iterator方法创建该对象。
下面是Iterator接口的定义:
public interface Iterator<T>{
    boolean hasNext();
    T next();
    void remove();
    }
如何使用迭代器:
Iterator<T> it = list.iterator();
        while(it.hasNext()){
            T data = it.next();
            System.out.print(data + " ");
        }
Collection转换为Object数组
Object[] toArray():返回一个内含集合所有元素的array
Object[]toArray(Object[] a)返回一个内含集合所有元素的array,运行期返回的array和参数a的类型相同,需要转化为正确的类型。

3.2 List接口
List接口继承了Collection接口,可以定义一个有重复项的有序集合。

1.面向位置的操作
包含Collection的功能,还包括获取、除去或更改元素的功能。在List中搜索元素可以从列表的头部或者尾部开始,如果找到,返回元素的位置。
void add(int index,Object elenemt)
boolean addAll(int index,Collection c);
Object get(int index)返回List中指定位置的元素
int indexOf(Object o)返回第一个出现o的位置
2.处理集合的子集
ListIterator listIterator():返回一个列表迭代器,用来访问列表中的元素

ArrayList和LinkedList
Java平台包含两种常用List实现:ArrayList和LinkedList。使用两种List的哪一种取决于特定的需要。如果要支持随机访问,而不必在尾部任何位置插入或者去除元素,那么,ArrayList提供了可选的集合。但如果要频繁的从列表的中间位置添加和去除元素,而只要顺序地访问列表中的元素,那么LinkedList实现更好。

LinkedList的方法:
getFirst()  
getLast()
获取元素,但不删除,操作失败,抛出异常(NoSuchElementException);
peekFirst()
peekLast()
获取元素,但不删除,失败返回null;
add:队尾入  remove:对头出  element:查看对头元素  失败抛异常  NoSuchElementException
offer:队尾入 poll 对头出   peek     失败返回null
练习代码:
public static void testArrayList(){
        //需要一个数组序列容器,=》ArrayList
        ArrayList<Integer> list1 = new ArrayList<Integer>();
        for(int i=0; i<10; ++i){
            list1.add((int)(Math.random()*100));
        }
        printList(list1);

        list1.add(0, 100);
        printList(list1);

        //list1.add(100, 200);
        int index = 0;
        if((index = list1.indexOf(100)) != -1){
            list1.remove(index);
        }
        printList(list1);

        list1.set(0, -2);
        printList(list1);

        Object[] array1 = list1.toArray();
        System.out.println(Arrays.toString(array1));

        Integer[] array2 = new Integer[1];//将容器元素返回到数组中
        array2 = list1.toArray(array2); //此处可以推到数组元素的类型的
        System.out.println(Arrays.toString(array2));

        List<Integer> list2 = Arrays.asList(array2);
        for(int val : list2){
            System.out.print(val + " ");
        }
        System.out.println();

        System.out.println(list1.retainAll(list2));
        System.out.println(list1.addAll(list2));
        System.out.println(list1.containsAll(list2));

    }
练习代码:
public static void testLinkedList(){
        LinkedList<Integer> list1 = new LinkedList<Integer>();
        for(int i=0; i<10; ++i){
            list1.add((int)(Math.random()*100));
        }
        printList(list1);

        list1.addFirst(10);
        printList(list1);

        list1.addLast(20);
        printList(list1);

        list1.add(30);
        printList(list1);

        list1.remove();
        printList(list1);

        list1.offer(40);
        printList(list1);

        list1.poll();
        printList(list1);

        System.out.println(list1.peek());

        list1.clear();
        System.out.println(list1.peek());


        //对于所有的Java集合容器,都支持普通的额向后遍历的迭代器
        //但对于LinkedList,还提供的双向迭代器
        ListIterator<Integer> list = list1.listIterator();
        System.out.println(list.hasPrevious());
    }   

**重点内容**ArrayList和LinkedList的区别?
(1)都是Llist接口实现的,但是LinkedList还实现了Deque;
(2)但是ArrayList底层是个数组,LinkedList底层是个双向循环链表;
(3)LinkedList提供了双向迭代器,ArrayList只有普通的向后遍历的迭代器;
(4)LinkedList便于删除插入,ArrayList便于查找;
(5)需要链表、栈、队列时最好实现LinkedList;


3.3 Queue接口
Queue接口除了可以使用Collection的方法,还提供了加入(offer())、删除(poll())等操作;
需要注意的是:Queue使用时要尽量避免Collection的add()和remove()方法,而是要使用offer()来加入元素,使用poll()来获并移除元素。他们的优点是通过返回值可以判断成功与否;

练习:
创建ArrayList对象,加入10000个随机整数,整数的范围是0-20000
请在最短时间内打印出最大的前10个元素!(PriorityQueue()小跟堆)
请在最短时间内打印出最小的前10个元素!(PriorityQueue()大根堆来实现)
代码如下:
class TestList{
public static void testPriorityQueue(){    //最小前10个元素(利用大根堆,将要插入的元素与堆根元素比较,堆根元素大于要插入的元素,这移出堆根元素,将新元素插入)
    PriorityQueue<Integer> queue= new PriorityQueue<Integer>(10,new Comparator<Integer>(){//利用构造函数变成大根堆

        @Override
        public int compare(Integer o1, Integer o2) {
            // TODO Auto-generated method stub
            int res=o1-o2;
            return res>0?-1:(res==0?0:1);
            }

    });
    ArrayList<Integer> list=new ArrayList<Integer>();
    for(int i=0;i<10000;i++){
        list.add((int)(Math.random()*20000));
    }   
    int size=10;
    for(int i=0;i<size;i++){
        queue.add(list.get(i));     
    }
    for(int i=size;i<10000;i++){
        int value=list.get(i);
        int data=queue.peek(); //返回头部元素 
        if(data>value){
            queue.remove(data);//删除
            queue.add(value);
        }   
    }
    while(!queue.isEmpty()){
        int top = queue.peek();
        System.out.print(top + " ");
        queue.poll();   //出队
    }
    System.out.println();
}
public static void testPriorityQueue1(){   //小根堆
    ArrayList<Integer> list=new ArrayList<Integer>();

    PriorityQueue<Integer> queue=new PriorityQueue<Integer>();
    for(int i=0;i<10000;i++){
        list.add((int)(Math.random()*20000));
    }

    int size=10;
    for(int i=0;i<size;i++){
        queue.add(list.get(i));

    }
    for(int i=size;i<10000;i++){
        int value=list.get(i);
        int data=queue.peek();  //peek返回头部元素
        if(data<value){
            queue.remove(data);
            queue.add(value);
        }
    }
    while(!queue.isEmpty()){
        int top = queue.peek();
        System.out.print(top + " ");
        queue.poll();
    }
    System.out.println();
}
}
public class TestCollectionDemo1 {

    @Test
    public void testPriorityQueue(){
        System.out.println("最小前10个元素 ");
        TestList.testPriorityQueue();
    }
    @Test
    public void testPriorityQueue1(){
        System.out.println("最大前10个元素");
        TestList.testPriorityQueue1();  
    }
}

运行结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值