资讯专栏INFORMATION COLUMN

集合概要学习---粗略

DesGemini / 3225人阅读

摘要:集合框架的基本接口类层次结构其中表示接口,表示实现类和在实际开发中,需要将使用的对象存储于特定数据结构的容器中。实例是迭代器,拥有两个方法方法迭代器用于遍历集合元素。返回值则是转换后的数组,该数组会保存集合中的所有元素。

Java Collections Framework是Java提供的对集合进行定义,操作,和管理的包含一组接口,类的体系结构。

Java集合框架的基本接口/类层次结构:

java.util.Collection [I]
+--java.util.List [I]
   +--java.util.ArrayList [C]
   +--java.util.LinkedList [C]
   +--java.util.Vector [C]
      +--java.util.Stack [C]
+--java.util.Set [I]
   +--java.util.HashSet [C]
   +--java.util.SortedSet [I]
      +--java.util.TreeSet [C]

java.util.Map [I]
+--java.util.SortedMap [I]
   +--java.util.TreeMap [C]
+--java.util.Hashtable [C]
+--java.util.HashMap [C]
+--java.util.LinkedHashMap [C]
+--java.util.WeakHashMap [C]

其中I表示接口,C表示实现类

1 List和Set

在实际开发中,需要将使用的对象存储于特定数据结构的容器中。JDK提供了这样的容器---集合(Collection)。Collection是一个接口,定义了集合相关的操作方法,其有两个子接口:List与Set

List:可重复集合
Set:不可重复的集合
其中判断元素是否重复,取决于元素的equals()比较的结果
2 集合持有对象的引用

集合中存储的都是引用类型元素,并且集合只保存每个元素对象的引用,而并非将元素对象本身存入集合。

3 集合中常用的方法: 3.1 add方法
Collection定义了一个add方法用于向集合中添加新元素。
boolean add(E e)
该方法返会将给定的元素添加进集合,若添加成功,则返回true,否则返回false。

实例1

import java.util.ArrayList;
import java.util.Collection;
public class Test00{
    public static void main(String[] args) {
        Collection c = new ArrayList();
        System.out.println(c);
        c.add("a");
        c.add("b");
        c.add("c");
        System.out.println(c);
    }
}
3.2 contains方法
boolean contains(Object o)
该方法用于判定给定的元素是否被包含在集合中。若包含则返回true,反则返回false。
注意:集合在判断元素是否被包含在集合中是根据每个元素的equals方法进行比较的结果。
通常有必要重写equals()保证contains()方法的合理结果

实例2:

import java.util.ArrayList;
import java.util.Collection;
public class Test00{
    public static void main(String[] args) {
        Collection c = new ArrayList();
        System.out.println(c);
        c.add("a");
        c.add("b");
        c.add("c");
        System.out.println(c);
        Collection b = new ArrayList();
        b.add("b");
        b.add("c");
        System.out.println(c.contains(b));
        System.out.println(c.contains("b"));
        c.addAll(b);
        System.out.println(c);
        System.out.println(c.contains(b));
        System.out.println(c.contains("h"));
    }
}
3.3 size clear isEmpty
int size()
该方法用于返回当前集合中的元素总数
void clear()
该方法用于清空当前集合。
boolean isEmpty()
该方法用于判定当前集合中是否不包含任何元素

实例3 :

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
public class Test00{
    public static void main(String[] args) {
        Collection c = new HashSet();
        System.out.println(c.isEmpty());
        c.add("java");
        c.add("cpp");
        c.add("php");
        c.add("c#");
        c.add("cpp");
        System.out.println("isEmpty : " + c.isEmpty() + ",size : "+ c.size());
        c.clear();// 清空该集合
        System.out.println("isEmpty : "+ c.isEmpty() + ",size : " + c.size());
    }
}

addAll  containsAll
boolean addAll(Collection  c)
该方法需要我们传入一个集合,并将该集合中的所有元素添加到当前集合中。
boolean containsAll(Collection c)
该方法用于判定当前结合是否包含给定集合中的所有元素,若包含则返回true。

实例4

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
public class Test00{
    public static void main(String[] args) {
        Collection c1 = new ArrayList();
        c1.add("java");
        c1.add("cpp");
        c1.add("php");
        c1.add("c#");
        c1.add("objective-c");
        c1.add("cppc");
        System.out.println(c1);
        Collection c2 = new HashSet();
        c2.addAll(c1);
        System.out.println(c2);
        Collection c3 =new ArrayList();
        c3.add("java");
        c3.add("cpp");
        System.out.println(c1.containsAll(c3));
    }
}
4 Iterator

Iterator是迭代器,拥有两个方法

4.1 hasNext,next方法
迭代器用于遍历集合元素。获取迭代器可以使用Collection定义的方法:

Iterator iterator()

迭代器Iterator是一个借口,集合在重写Collection的iterator()方法时利用内部类提供了迭代器的实现。

Iterator提供了统一的遍历元素集合的方法,其提供了用于遍历集合的两个方法:
boolean hasNext():判断集合是否还有元素可以遍历
E next():返回迭代的下一个元素

实例4

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
public class Test00{
    public static void main(String[] args) {
        Collection c = new HashSet();
        c.add("java");
        c.add("cpp");
        c.add("php");
        c.add("c#");
        c.add("objective-c");
        Iterator iterator = c.iterator();
        while(iterator.hasNext()){
            String str = iterator.next();
            System.out.println(str);
        }
    }
}
4.2 remove方法

在使用迭代器遍历集合时,不能通过集合的remove方法删除集合元素,否则会抛出并发更改异常。我们可以通过迭代器自身提供的remove()方法来删除通过next()迭代出的元素

void remove()

迭代器的删除方法是在原集合中删除元素。

这里需要注意的是:在调用remove方法前必须通过迭代器的next方法迭代过的元素,那么删除的就是这个元素。并且不能够再次调用remove方法,除非再次调用next()后方可再次调用。

实例5:

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
public class Test00{
    public static void main(String[] args) {
        Collection c = new HashSet();
        c.add("java");
        c.add("cpp");
        c.add("php");
        c.add("c#");
        c.add("objective-c");
        Iterator it = c.iterator();
        while(it.hasNext()){
            String str =  it.next();
            if(str.indexOf("c")!=-1){
                it.remove();// 删除包含字母c的元素
            }
        }
        System.out.println(c);
    }
}

4.3 增强型for循环

Java5.0之后推出了一个新的特性,增强for循环,也成为新循环。该循环不通用于传统循环的工作,其只用于遍历集合或数组。

语法:
for(元素类型 e:集合或数组){
   循环体
}

实例7

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
public class Test00{
    public static void main(String[] args) {
        Collection c = new HashSet();
        c.add("java");
        c.add("cpp");
        c.add("php");
        c.add("c#");
        c.add("objective-c");
        for(String str : c)
        {
            System.out.print(str.toUpperCase()+" ");
            //C# CPP OBJECTIVE-C JAVA PHP 
        }
    }
} 

新循环并非新的语法,而是在编译过程中,编译器会将新循环转为迭代器模式。所以新循环本质上是迭代器。

5 泛型机制

泛型是Java SE5.0引入的特性,泛型的本质是参数化类型。在类、接口、和方法的定义过程中,所操作的数据类型被传入的参数指定。

Java泛型机制广泛的应用在集合框架中。所有的集合类型都带有泛型的参数,这样在创建集合时可以指定放入集合中的元素的类型。Java编译器可以据此进行类型检查,这样可以减少代码在运行时出现错误的可能性。

6 List

List接口是Collection的子接口,用于定义线性表数据结构。可以讲List理解为存放对象的数组,只不过其元素可以动态的增加或减少。
List接口的两个常见实现类为ArrayList和LinkList,分别用动态数组和链表的方式实现了List接口。
可以认为ArrayList和LinkedList的方法在逻辑上完全一样,只是在性能上有一定差别。ArrayList更适合于随机访问,LinkList更适合于插入和删除。在性能要求不是特别苛刻的情形下可以忽略这个差别。

6.1 get和set

List除了继承Collection定义方法外,还根据其线性表的数据结构定义了一系列的方法,其中最常用的就是基于下标的get和set方法

E get(int index)
获取集合执行下标对应的元素,下标从0开始。
E set(int index,Element)
将给定的元素存入给定位置,并将原位置的元素返回。

实例8

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
public class Test00{
    public static void main(String[] args) {
        List c = new ArrayList();
        c.add("java");
        c.add("cpp");
        c.add("php");
        c.add("c#");
        c.add("objective-c");
        for(int i = 0;i
6.2 插入和删除

List根据下标的操作还支持插入语删除操作

void add(int index,Element);
将给定的元素插入到指定位置,原位置及后续元素都顺序向后移动。

E remove(int index);
删除给定位置的元素,并将被删除的元素返回。

6.3 List转换为数组

List的toArray方法用于将集合转换为数组。但实际上该方法是在Collection中定义的,所以所有的集合都具备这个功能。

其有两个方法:
Object[] toArray()
T[] toArray(T[] a)

其中第二个方法是比较常用的,我们可以传入一个指定类型的数组,该数组的元素类型与集合的元素类型一致。返回值则是转换后的数组,该数组会保存集合中的所有元素。

6.4 数组转换为List

Arrays类中提供了一个静态方法asList,使用该方法我们可以将一个数组转换为对应的List集合。
其方法定义为:

static List asList

返回的List的集合元素类型由传入的数组的元素类型决定。
并且要注意的是,返回的集合我们不能对其增删元素。并且对集合的元素进行修改hi影响数组对应的元素。

6.5 List排序

Collection.sort方法实现排序
Collection是集合的工具类,它提供了很多便于我们操作集合的方法,其中就有用于集合排序的sort方法。该方法定义为:

void sort(List list)
该方法的作用是对给定的集合元素进行自然排序。
6.6 Comparable

Collection的sort方法是对集合元素进行自然排序,那么两个元素对象之间就一定要有大小之分。这个代销之分是如何界定的?

实际上,在使用Collection的sort排序的结合都必须是Comparable接口实现类,该接口表示其子类是可比较的,因为实现该接口必须重写抽象方法:

int compareTo(T t);
该方法返回值要求:
若o1>o2则返回值应>0
若o1
6.7 LinkedList
双向链表
    双端效率高

方法

add(数据)    添加数据
get(i)        访问指定位置的收
remove(i)     移除指定位置的数据
size()        元素的数量
addFirst()    在链表首处添加元素
addLast()    在链表末尾添加元素
getFirst()    获得第一个元素
getLast()    获得末尾元素
removeFirst()    删除第一个元素
removeLast()    删除最后一个元素
iterator()
    辅助创建迭代器对象进行设置

LinkedList实例:

    import java.lang.reflect.Array;
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.Queue;
    
    public class Test00{
        public static void main(String[] args) {
            LinkedList list = new LinkedList<>();
            list.add("aaa");
            list.add("bbb");
            list.add("ccc");
            list.add("ffffd");
            list.add("eee");
            list.add("fff");
            list.add("ggg");
            list.add("hhh");
            list.add("iii");
            list.add("jjj");
            list.add("kkk");
            list.add("lll");
                
            System.out.println("获取链表数组的大小: "+list.size());// 获取链表的大小
            System.out.println("get方法获取元素 "+list.get(0));
            System.out.println("获取第一个元素"+list.getFirst());
            System.out.println("获取链表的之后一个元素 "+list.getLast());
            
            LinkedList list1 = new LinkedList<>();
            list1.addAll(list);
            for(String s1:list1){// 元素遍历
                System.out.println(s1);
            }
             // 通过迭代器来遍历
            Iterator iterator = list.iterator();
            
            if(iterator.hasNext()){
                String str = iterator.next();
                System.out.println(str);
            }
            
            System.out.println("删除链表的第一个元素 "+list.removeFirst());
            System.out.println("删除链表的最后一个元素: "+list.removeLast());
            System.out.println("找到第一个相等的元素进行删除  "+list.remove("ffffd"));
            System.out.println("指定删除链表中的某个元素:"+list.remove(4));
            System.out.println(list.toArray());// 将list链表转为数组
            Object[] listarr = list.toArray();// 将list转为数组,并利用数组的方式进行答应
            System.out.println(Arrays.toString(listarr));
        }
    }

6.8 ArrayList和LinkedList的大致区别如下:

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据  

示例如下:

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Test00{
    static final int N = 500000;
    static long timeList(List list){
        long start = System.currentTimeMillis();
        Object o = new Object();
        for(int i = 0;i
7 队列和栈
7.1 Queue(队列)
队列是常用的数据结构,可以将队列看成特殊的线性表,队列限制了线性表的访问方式:只能从线性表
的一端添加(offer)元素,从另一端取出(poll)元素。

队列遵循先进先出(FIFO First Input First Output)的原则。

JDK中提供了Queue接口,同时使用LinkedList实现了该接口(选择LinkList实现Queue的原因在于
Queue经常要进行添加和删除的操作,而LinkList在这方面效率较高)。

Queue接口中主要方法如下:

boolean off(E e)     将一个元素添加至队尾,如果添加成功则返回true。
E poll()             从队首删除并返回一个元素。
E peek()            返回队首的元素(但并不删除).

7.2 Deque

Deque是Queue的子接口,定义了所谓的"双端队列",即从队列的两端分别可以入队(offer)和出队(poll),LinkList实现了该接口。
如果将Deque限制为只能从一端入队和出队,则可实现"栈"(Stack)数据结构,对栈而言,入栈称之为push,出栈称之为pop。
栈遵循先进后出(FILO First Input Last Output)的原则。

import java.util.LinkedList;
import java.util.Queue;
public class Test00{
    public static void main(String[] args) {
        Queue queue = new LinkedList();
        queue.offer("a");// 将一个对象添加至队尾,如果添加成功则返回true
        queue.offer("b");
        queue.offer("c");
        System.out.println(queue);
        String str =queue.peek();
        System.out.println(str);
        while(queue.size()>0){
            // 从队首删除并返回一个元素
            str  = queue.poll();
            System.out.println(str + " ");
        }
        
    }
}

文章参考:http://blog.sina.com.cn/s/blo...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76605.html

相关文章

  • charles抓包工具粗略使用指南

    摘要:常用的抓包工具有当然还有其他的工具我三个都用过不过太复杂了不是太懂用抓到的信息太详细了反而不是太容易分辨找出自己想要的内容其实是因为懒懒的学并且对网络知识了解较少境界不够境界到了自然会用我一般都是开发的时候用到抓包工具开发网页自带的就已经很 常用的抓包工具有fiddler,charles,wireshark(当然还有其他的工具)我三个都用过,不过wireshark太复杂了,不是太懂用,...

    felix0913 评论0 收藏0
  • Java8学习小记

    摘要:但有一个限制它们不能修改定义的方法的局部变量的内容。如前所述,这种限制存在的原因在于局部变量保存在栈上,并且隐式表示它们仅限于其所在线程。 2014年,Oracle发布了Java8新版本。对于Java来说,这显然是一个具有里程碑意义的版本。尤其是那函数式编程的功能,避开了Java那烦琐的语法所带来的麻烦。 这可以算是一篇Java8的学习笔记。将Java8一些常见的一些特性作了一个概要的...

    CHENGKANG 评论0 收藏0
  • dubbo源码解析——概要

    摘要:服务提供者代码上面这个类会被封装成为一个实例,并新生成一个实例。这样当网络通讯层收到一个请求后,会找到对应的实例,并调用它所对应的实例,从而真正调用了服务提供者的代码。 这次源码解析借鉴《肥朝》前辈的dubbo源码解析,进行源码学习。总结起来就是先总体,后局部.也就是先把需要注意的概念先抛出来,把整体架构图先画出来.让读者拿着地图跟着我的脚步,并且每一步我都提醒,现在我们在哪,我们下一...

    Meathill 评论0 收藏0
  • for-loop 与 json.Unmarshal 性能分析概要

    摘要:原文地址与性能分析概要前言在项目中,常常会遇到循环交换赋值的数据处理场景,尤其是,数据交互格式要转为,赋值是无法避免的。如下预编译生成代码提前确定类型,可以解决运行时的反射带来的性能开销。 原文地址:for-loop 与 json.Unmarshal 性能分析概要 前言 在项目中,常常会遇到循环交换赋值的数据处理场景,尤其是 RPC,数据交互格式要转为 Protobuf,赋值是无法避免...

    zorro 评论0 收藏0
  • 高性能的网页开发概要

    摘要:或者说一直以来我是缺乏开发高性能网页的意识的,但是想做一个好的前端开发者,是需要在当自己编写的程序慢慢复杂以后还能继续保持网页的高性能的。 不知道有多少人和我一样,在以前的开发过程中很少在乎自己编写的网页的性能。或者说一直以来我是缺乏开发高性能网页的意识的,但是想做一个好的前端开发者,是需要在当自己编写的程序慢慢复杂以后还能继续保持网页的高性能的。这需要我们对JavaScript语句,...

    bovenson 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<