带你轻松搞定Java面向对象的编程--数组,集合框架

目录
  • 一、数组
    • 1.数组的定义
    • 2.数组的声明
    • 3.数组的初始化
  • 二、集合概述
  • 三、Collection接口
    • 1.Collection接口概述
    • 2.集合框架的三个组件
    • 3.Iterator接口
  • 四、List接口
    • 1.ArrayList类
    • 2.LinkedList类
  • 五、Set接口
    • 1.HashSet类
  • 六、Map接口
    • 1.HashMap类
  • 七、泛型
  • 总结

一、数组

1.数组的定义

数组是为了解决同类数据整合摆放而提出的,可以理解为一组具有相同类型的变量的集合,它的每个元素都具有相同的数据类型。

2.数组的声明

1.<data_type>[] <array_name>;
2.<data_type> <array_name>[];

例如定义保存学生成绩的语法:

1.float[] scores;
2.float scores[];

虽说两种写法都没错,但是按照Java语言的变成习惯,推荐各位采用第一种写法,即把中括号放在数据类型和变量名中间。

注意:

  • 数组的类型实际上是指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。
  • 项目数组名的书写规则应符合标识符的书写规定。
  • 数组名不能与其他变量名相同
  • 在数组声明中包含数组长度永远是不合法的,如float[] scores;。因为,声明的时候并没有实例化任何对象(没有分配空间),只有在实例化对象时,JVM才分配空间,这时才与长度有关。

3.数组的初始化

数组有两种初始化

  • 静态初始化

静态初始化的方式是在声明数组变量的同时进行的。这种方式不仅定义了数组中包含的元素的数量,而且制定了每个元素的值。

注意,静态初始化应该在一条语句内完成,不能分开写。

例如:

float[] scores = {93.5f,83,61,80};
int[] arr ={1,2,3,4,5};
  • 动态初始化

动态初始化的方式是在声明数组时就必须定义数组的大小,以及每个元素的初始值。如果要定义的数组长度或数组数据只有在运行时才能决定,就要使用动态初始化。

注意,动态初始化时也可以使用变量的值来定义数组大小

例如:

int[] arr;
arr = new  int[10];
char[] c = new char[100];
int[] d = new int[]{1,2,3,4};

抽象类的使用原则如下:

(1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;

(2)抽象类不能直接实例化,需要依靠子类采用向上转型的方式处理;

(3)抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类;

(4)子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法(如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。)

二、集合概述

java.util包中提供了所有用到的集合类。

集合 简单来说就是存储对象容器

集合中可存储任意类型的对象,最重要的是长度可变

不过集合类存放的都是对象的引用,而非对象本身,集合也不能存储基本数据类型

下图是集合框架

三、Collection接口

1.Collection接口概述

Collection是单向集合。Set接口、List接口都是Collection接口的子接口

2.集合框架的三个组件

集合类主要有Set、List、Map

  • Set(集):无序、不可重复
  • List(列表):有序,可重复 常用的列表类有Vector、Stack、LinkedList、ArrayList
  • Map(映射):保存的是键值对(key-value),映射中存储的每个对象(value)都有一个相关的关键字(key)对象。一个Map对象的每一个关键字应是惟一的(否则key可能对应多个value),就是说key-value是单向一对一的关系 常用的映射类有HashTable、HashMap、TreeMap

由于Set和List都是Collection的子接口,那么Set和List的所有实现类都实现了下面所示的Collection的方法

方法 摘要
boolean add(E e) 确保此集合包含指定的元素(可选操作)
boolean addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到此集合(可选操作)
void clear() 从此集合中删除所有元素(可选操作)
boolean contains(Object o) 如果此集合包含指定的元素,则返回 true )
boolean containsAll(Collection<?> c) 如果此集合包含指定 集合中的所有元素,则返回true
boolean isEmpty() 如果此集合不包含元素,则返回 true
Iterator iterator() 返回此集合中的元素的迭代器
boolean remove(Object o) 从该集合中删除指定元素的单个实例(如果存在)(可选操作)
Object[] toArray() 返回一个包含此集合中所有元素的数组
T[] toArray(T[] a) 返回包含此集合中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型

3.Iterator接口

所谓的“Collection是所有集合类的跟接口”,并不意味着Collection就是“根”。其实,Collection是Iterator接口的子接口,只不过Iterator(迭代器)不属于集合的范畴而已,那么Iterator接口作用是什么呢?

Iterator叫做“迭代器”,它允许访问一个容器(container)对象中的各个元素,而又不需要公开该对象的内部细节,从定义上看,迭代器为容器而生。由Collection接口继承了Iterator,所以所有集合对象都可以被迭代,Collection接口内定义了 iterator() 方法,能获得一个Iterator迭代器,从而实现对集合的迭代。

迭代器的用法:

Iterator it = Collection.iterator();
while(it.hasNext()){
	Object obj = it.next();
}

Iterator如何对ArrayList进行迭代

public class IteratorDemo  {
    public static void main(String[] args) {
    	//创建List集合对象
    	List<String> alist = new ArrayList<String>();
    	alist.add("a");
    	alist.add("b");
    	alist.add("c");
    	alist.add("d");
       //设定迭代内容为String对象
        Iterator<String> it = alist.iterator();
		while(it.hasNext()){
			//此时就可以直接使用String来接收返回值了
			String s = it.next();
			System.out.println(s);
		}
  	}
}

四、List接口

List继承了Collection,是有序的列表,该接口定义的元素是有序的且可重复的。在List接口下使用最多的就是ArryList实现类和LinkList实现类。

1.ArrayList类

ArrayList类是List接口的大小可变数组的实现(继承AbstractList,同时实现List接口)。

ArrayList是动态数组,所以保持了数组的特性。在ArrayList执行查询操作将非常,但如果执行增加(特别是插入)、删除操作,效率低下

ArrayList类的特点如下:

  • 大小是可变的,是自动增长的,可动态的增加或减少元素,可存储null值
  • 实现了ICollection 和 IList 接口
  • 它是非同步的集合类
  • 元素可以重复

构造方法

在这里我只写一种构造方法

ArrayList<Object> alist = new ArrayList<Object>;

ArrayList类的方法:

方法 摘要
boolean add(E e) 将指定的元素追加到此列表的末尾
void add(int index, E element) 在此列表中的指定位置插入指定的元素。
boolean addAll(Collection<? extends E> c) 按指定集合的Iterator返回的顺序将指定集合中的所有元素追加到此列表的末尾
boolean addAll(int index, Collection<? extends E> c) 将指定集合中的所有元素插入到此列表中,从指定的位置开始
void clear() 从此集合中删除所有元素
Object clone() 返回此 ArrayList实例的浅拷贝
boolean contains(Object o) 如果此集合包含指定的元素,则返回 true )
void ensureCapacity(int minCapacity) 如果需要,增加此 ArrayList实例的容量,以确保它可以至少保存最小容量参数指定的元素数
void forEach(Consumer<? super E> action) 对 Iterable的每个元素执行给定的操作,直到所有元素都被处理或动作引发异常
E get(int index) 返回此列表中指定位置的元素
int indexOf(Object o) 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1
boolean isEmpty() 如果此列表不包含元素,则返回 true
E remove(int index) 删除该列表中指定位置的元素
boolean remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)
E set(int index, E element) 用指定的元素替换此列表中指定位置的元素
int size() 返回此列表中的元素数
List subList(int fromIndex, int toIndex) 返回此列表中指定的 fromIndex (包括)和 toIndex之间的独占视图
Object[] toArray() 以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的数组
T[] toArray(T[] a) 以正确的顺序返回一个包含此列表中所有元素的数组(从第一个到最后一个元素); 返回的数组的运行时类型是指定数组的运行时类型

2.LinkedList类

ArrayList类用于创建链表数据结构对象。与ArrayList一样,LinkedList也实现了List接口,这说明可根据索引来查询集合内的元素。

由于LinkedList实现了双向循环链表,所以可以很快捷插入或删除元素;但由于链表的特性,如果对LinkedList执行查询,那么效率也非常。可以说ArrayList和LinkedList是互补关系

构造方法

在这里我只写一种构造方法

LinkedList<Object> llist = new LinkedList<Object>;

LinkedList类的方法:

方法 摘要
boolean add(E e) 将指定的元素追加到此列表的末尾
void add(int index, E element) 在此列表中的指定位置插入指定的元素
boolean addAll(Collection<? extends E> c) 按照指定集合的迭代器返回的顺序将指定集合中的所有元素追加到此列表的末尾
boolean addAll(int index, Collection<? extends E> c) 将指定集合中的所有元素插入到此列表中,从指定的位置开始
void addFirst(E e) 在该列表开头插入指定的元素
void addLast(E e) 将指定的元素追加到此列表的末尾
void clear() 从列表中删除所有元素
boolean contains(Object o) 如果此列表包含指定的元素,则返回 true
E element() 检索但不删除此列表的头(第一个元素)
E get(int index) 返回此列表中指定位置的元素
E getFirst() 返回此列表中的第一个元素
E getLast() 返回此列表中的最后一个元素
int indexOf(Object o) 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1
int lastIndexOf(Object o) 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1
ListIterator listIterator(int index) 从列表中的指定位置开始,返回此列表中元素的列表迭代器(按适当的顺序)
E remove() 检索并删除此列表的头(第一个元素)
E remove(int index) 删除该列表中指定位置的元素
boolean remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)
E removeFirst() 从此列表中删除并返回第一个元素
E removeLast() 从此列表中删除并返回最后一个元素
E set(int index, E element) 用指定的元素替换此列表中指定位置的元素
int size() 返回此列表中的元素数
Object[] toArray() 以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的数组
T[] toArray(T[] a) 以正确的顺序返回一个包含此列表中所有元素的数组(从第一个到最后一个元素); 返回的数组的运行时类型是指定数组的运行时类型

五、Set接口

Set接口 继承Collection接口。他存储的是无序的,惟一的集合元素

1.HashSet类

实现了Set接口,是基于HashMap实现,存储不重复,无序值

HashSet 是根据对象的哈希值来确定元素在集合中的存储位置,元素再插入时就确定了存储位置,因此,元素在集合中的存储位置时固定的(无序是指输出顺序 与存出顺序不一致),具有良好的存储和查询性能(存储速度快)。

构造方法

在这里我只写一种构造方法

Set ss = new HashSet();

HashSet 类常用的方法:

方法 摘要
boolean add(E e) 将指定的元素添加到此集合(如果尚未存在)
boolean remove(Object o) 如果存在,则从该集合中删除指定的元素
int size() 返回此集合中的元素数(其基数)

六、Map接口

Map接口 是一个根接口,他存储的是键-值对(key-value),其中key不允许重复,value允许重复。

1.HashMap类

HashMap类 实现了Map接口,存储的是无序的键-值对(key-value)。

  • HashMap的key是用Set集合来存放,所以想做到key不允许重复,key对应的类需要重写hashCode()和equals()方法
  • HashMap是线程不安全
  • HashMap中的元素的位置是不定时的更新,即元素位置不固定

构造方法

在这里我只写一种构造方法

HashMap map = new HashMap();

HashMap 类常用的方法:

方法 摘要
V put(K key, V value) 将指定的值与此映射中的指定键相关联
V get(Object key) 返回到指定键所映射的值,或 null如果此映射包含该键的映射
int size() 返回此地图中键值映射的数量
V remove(Object key) 从该地图中删除指定键的映射(如果存在)

七、泛型

为什么要使用泛型程序设计?以常用的ArrayList类为例,在使用ArrayList的时候常遇到以下两个问题

  • 当获取一个值的时候必须进行强制类型转换
  • 当向其中放入值的时候没有任何约束,只要是对象就行。

这样,如果处理数据类型时稍微出现一点问题,程序就会报错!

泛型提供了一个解决方案:类型参数(type parameters)。如果ArrayList类有一个类型参数指示元素的类型,就没有问题了

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

这时程序员可以很方便的分辨其中元素的类型,编译器也可以很好的利用这个信息。所以当调用get()方法时,不需要执行类型转换,编译器就可以返回值类型为String。

String str = arr.get(0);

编译器还知道ArrayList < String> 中add()方法有一个类型为String的参数。这将比直接使用Object类型的参数安全。如果在尝试向其中放入非String的数据,编译器就会发出通知,以避免发生错误。

arr.add(new Integer(1));

总结

本篇文章的内容就到这了,希望大家可以喜欢,也希望大家可以多多关注我们的其他精彩内容!

(0)

相关推荐

  • Java源码分析:Guava之不可变集合ImmutableMap的源码分析

    目录 一.案例场景 二.ImmutableMap源码分析 总结 一.案例场景 遇到过这样的场景,在定义一个static修饰的Map时,使用了大量的put()方法赋值,就类似这样-- public static final Map<String,String> dayMap= new HashMap<>(); static { dayMap.put("Monday","今天上英语课"); dayMap.put("Tuesday&quo

  • 带你入门Java的集合

    目录 java集合 集合分类---Set.List.Map三种大体系 Set HashSet HashCode()方法 TreeSet 自然排序 List List与ArrayList ArrayList和Vector Map TreeMap 操作集合的工具类:Collections 查找.替换 同步控制 泛型 为什么要有泛型 枚举类 Annotation(注解)概述 基本的Annotation 自定义Annotation 总结 java集合 java集合类存放于java.util包中,是一个用

  • java集合类HashMap源码解析

    Map集合 Map集合存储的是键值对 Map集合的实现类: HashTable.LinkedHashMap.HashMap.TreeMap HashMap 基础了解: 1.键不可以重复,值可以重复: 2.底层使用哈希表实现: 3.线程不安全: 4.允许key为null,但只允许有一条记录为null,value也可以为null,允许多条记录为null: 源码分析 (一)以JDK1.7为例 1.存储结构 数据结构:数组+链表 首先hashmap内部有一个Entry类型的数组table: 通过Entr

  • Java JUC中操作List安全类的集合案例

    目录 不安全的集合 Java中提供的安全措施 JUC下的安全List集合 性能方面 不安全的集合 在单线程应用中,通常采取new ArrayList(),指定一个List集合,用于存放可重复的数据. 但在多线程下,往往会出现意想不到的问题,代码如下所示: import java.util.*; public class ListTest { public static void main(String[] args) throws InterruptedException { // 创建list

  • 为什么在foreach循环中JAVA集合不能添加或删除元素

    1. 编码强制规约 在<阿里巴巴Java开发手册>中,针对集合操作,有一项规定,如下: [强制]不要在 foreach 循环里进行元素的 remove/add 操作.remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁. public class SimpleTest { public static void main(String[] args) { List<String> list = Lists.newArrayList(); l

  • 带你轻松搞定Java面向对象的编程--数组,集合框架

    目录 一.数组 1.数组的定义 2.数组的声明 3.数组的初始化 二.集合概述 三.Collection接口 1.Collection接口概述 2.集合框架的三个组件 3.Iterator接口 四.List接口 1.ArrayList类 2.LinkedList类 五.Set接口 1.HashSet类 六.Map接口 1.HashMap类 七.泛型 总结 一.数组 1.数组的定义 数组是为了解决同类数据整合摆放而提出的,可以理解为一组具有相同类型的变量的集合,它的每个元素都具有相同的数据类型.

  • 带你快速搞定java多线程

    目录 1.什么是线程 2.线程的状态 3.怎么通俗理解进程,线程? 4.线程和进程的区别 5.什么是线程安全 6.如何创建线程 总结: 1.什么是线程 线程是操作系统调度的最小单元,也叫轻量级进程.它被包含在进程之中,是进程中的实际运作单位.同一进程可以创建多个线程,每个进程都有自己独立的一块内存空间.并且能够访问共享的内存变量. 2.线程的状态 线程的状态一般看到的也就是Runable 和blocked ,最多的还是blocked,因为cpu的时间片很短,切换的很快等待IO,等待临界资源.大概

  • 带你快速搞定java IO

    目录 一.IO底层是怎么回事? 二.梳理类的结构 三.IO类大点兵 四.来波实例展示 1.访问操作文件(FileInputStream/FileReader ,FileOutputStream/FileWriter) 2.缓存流的使用(BufferedInputStream/BufferedOutputStream,BufferedReader/BufferedWriter) 3.获取键盘输入 总结: 一.IO底层是怎么回事? 操作系统就是管家,电脑的设备就是资源,如果进程先要操作资源,必须要进

  • 带你快速搞定java多线程(4)

    目录 1.AQS 是什么? 2.AQS 模型 3.AQS state 4.AQS 两种资源共享方式: 5.模板方式实现自定义 6.锁的分类:公平锁和非公平锁,乐观锁和悲观锁 7.CAS 8.总结 1.AQS 是什么? AQS 是类 AbstractQueuedSynchronizer的简称,也是常用锁的基类,比如常见的ReentrantLock,Semaphore,CountDownLatch 等等. AQS提供了一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架.是Java提供的一种模板

  • 四步轻松搞定java web每天定时执行任务

    本文介绍了java web每天定时执行任务,分享给大家,具体如下: 第一步: package com.eh.util; import java.util.Calendar; import java.util.Date; import java.util.Timer; /** * java定时任务,每天定时执行任务 * @author wls * */ public class TimerManager { //时间间隔 private static final long PERIOD_DAY =

  • 带你快速搞定java多线程(3)

    目录 一.锁的概念 二.synchronized 的使用方式 三.synchronized 的实现原理列 小结 四.线程池是什么 五.为什么要用线程池? 六.看下类图,从整体上理解下 七.线程池的创建 八.线程池核心参数说明 九.几个疑问点 9.1.是怎么保证线程不销毁的? 9.2 提交任务有哪几种方式? 9.3 拒绝策略都有哪些? 9.4 线程池的关闭 9.5 初始化线程池时线程数的选择 十.总结 一.锁的概念 先来聊聊这几个概念,总不能聊起来的时候啥也不知道,只知道干活也没有用. 公平锁:当

  • 带你快速搞定java并发库

    目录 一.总览 二.Executor总览 三.继承结构 四.怎么保证只有一个线程 五.怎么保证时间可以定时执行 六.使用 总结 一.总览 计算机程序 = 数据 + 算法. 并发编程的一切根本原因是为了保证数据的正确性,线程的效率性. Java并发库共分为四个大的部分,如下图 Executor 和 future 是为了保证线程的效率性 Lock 和数据结构 是为了维持数据的一致性. Java并发编程的时候,思考顺序为, 对自己的数据要么加锁.要么使用提供的数据结构,保证数据的安全性 调度线程的时候

  • 带你快速搞定java多线程(5)

    目录 1.介绍 2.countdownlantch的用法. 3.如何利用AQS 实现 CountDownLatch 4.总结 1.介绍 CountDownLantch 倒数计时器,一个同步辅助类,一个线程(或者多个),等待另外N个线程完成某个事情后才能执行.用给定的计数初始化CountDownLatch,其含义是要被等待执行完的线程个数. 每次调用CountDown(),计数减1,执行到await()函数会阻塞等待线程的执行,直到计数为0. CountDownLantch 无法重置 2.coun

  • 带你快速搞定java多线程(2)

    目录 1.Future的类图结构,从整体上看下Future的结构 2.future的使用,说的再多都么什么用,来个例子悄悄怎么用的. 3.通俗理解 4.原理 5.总结 1.Future的类图结构,从整体上看下Future的结构 首先看下future接口的函数,共有5个方法. get() 获取执行的结果,另外一个重载是有时间限制的get ,如果超时会有异常 isDone() 判断future 结果是否处理完成 cancel 取消任务 2.future的使用,说的再多都么什么用,来个例子悄悄怎么用的

  • 带你快速搞定java数组

    目录 1.数组的定义 2.array 遍历 3.List和array 之间的转换 1.数组转list 2.list 转数组 3.Arrays工具类 4.可能遇到的问题 总结 1.数组的定义 先声明后使用 数据类型 [] 数组名称 = new 数据类型[长度];String[] arr3 = new String[5]; 数据类型 数组名称[] = new 数据类型[长度];String arr[] = new String[5]; 直接初始化 String[] arrs = {"1",

随机推荐