**Set接口里面存放的是元素是无序的,不可以有重复元素,可以包含null **Set集合只有一种取出方式,就是迭代器Iterator **Set集合功能和Collection是一致的,没有特殊方法 |--->HashSet: **集合里面存放的元素是无序的,唯一的 **底层数据结构是哈希表,哈希表结构的数据都是无序的,哈希表结构的操作效率都高效 **线程不同步 **保证元素唯一性的原理是:通过复写hashCode和equals方法 ****如果两元素的hashCode值相同,则继续判断两元素equals是否为真 ****如果两元素的hashCode值不同,则不会调用equals方法。 **当我们往HashSet集合存放自定义的元素时(比如学生对象),通常都要复写hashCode和equals方法, 而且hashCode和equals方法不通过我们调用,HashSet集合底层内部自己调用,自己拿元素去比较 |--->TreeSet **TreeSet集合可以对存放的元素进行排序,弥补了Set集合元素无序的缺点,且元素是唯一的 **底层数据结构是二叉树,二叉树结构都是有序的 **线程不同步 **TreeSet集合要求往集合里存放的元素自身具备比较性,否则会报错 **TreeSet集合保证元素唯一性的依据是:通过compareTo或者compare方法中的来保证元素的唯一性。 TreeSet排序的第一种方式:让元素自身具备比较性, 定义元素类实现Compareble接口,覆盖compare方法, 此方式是元素的自然顺序。 TreeSet排序的第二种方式:让集合具备比较性 当元素自身不具备比较性或者具备的比较性不是 我们所需要的比较性时,此时就需要让集合具备自定义的比较性。 那如何让集合自身具备比较性呢? 可在集合初始化时,就让集合具备比较方式。 即定义一个类,实现Comparator接口,覆盖compare方法。 注: **判断元素唯一时,当主要条件一样时,判断次要条件 **两种排序方式都在时,以比较器为主!!! (4)Map集合: |--Hashtable 底层是哈希表结构 线程安全的,并且键和值不能为null。 |--HashMap 底层是哈希表结构 线程不安全的,键和值可以为null。 |--LinkedHashMap
底层是链表和哈希表 线程不安全 |--TreeMap 底层是二叉树 线程不安全的
12、如果你想将一组对象按一定顺序存取,在不考虑并发访问的情况下会使用____C_____ , 反之则会使用____A_____;如果你想存储一组无序但唯一的对象,你会使用___B______ ; 如果你想按关键字对对象进行存取,在不考虑并发访问的情况下会使用___D______ ,反之则会使用_____E____。 A. Vector B. HashSet C. ArrayList D. HashMap E. Hashtable 13、泛型: (1)为什么会出现泛型? 因为集合存放的数据类型不固定,故往集合里面存放元素时,存在安全隐患, 如果在定义集合时,可以想定义数组一样指定数据类型,那么就可以解决该类安全问题。 JDK1.5后出现了泛型,用于解决集合框架的安全问题。 泛型是一个类型安全机制。 (2)泛型定义格式:通过<>来定义要操作的引用数据类型 ArrayList
**泛型接口: 当泛型定义在接口上时,则子类中要指定实现接口类型,同时还可以子类也可以定义为泛型类 (6)泛型的高级应用:?通配符 **当指定两种泛型的集合,则迭代时也要定义两种泛型的迭代器,麻烦,此时可通过将迭代器的泛型 改为?,如Iterator> it=al.iterator(); **两种泛型限定 向上限定: ? extends E ;E可以接收E类型或者E的子类 向下限定: ? super E ;E可以接收E类型或者E的父类 14、高级for循环 (1)JDK1.5新特性,代替迭代器使用时的不爽,简化书写,底层原理是迭代器凡是支持迭代器的都支持高级for循环 高级for循环,只用于集合和数组的遍历,集合只能用Collection不能用Map集合 只能把Map集合转化成Set集合,才能用for循环。 (2)格式 for(数据类型 变量名:被遍历的集合(Collection)或者数组) { }
(3)局限性: 必须要有遍历的目标 对集合或者数组进行遍历时,只能获取集合元素,不能对集合元素进行操作 迭代器除了遍历,还可以进行remove操作集合中的元素 列表迭代器还可以在遍历过程中进行增删改查的操作 (4)传统for循环和高级for循环的区别 高级for循环有一个局限性,就是必须要有遍历的目标(集合或者数组) 遍历数组时建议使用传统for循环,因为可以定义角标,比如打印100次helloworld时用传统for循环方便 15、可变参数 (1)数组的可变参数 格式: int... arr (3)方法的可变参数 格式: public static void show(String str,int... arr) { } 注意:可变参数一定要放在参数列表的最后面 16、静态导入: **import static java.util.Arrays.* 导入的是Arrays这个类中所有的静态方法 **当类名重名时,需要制定具体的报名 **当方法重名时,需要制定具体所属的对象或者类
17、Collections类: (1)此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。 (2)静态方法摘要: static
B:如果数组中的元素都是基本数据类型,则该数组变成集合时,会将该数组作为集合的一个 元素出入集合 C:如果数组中的元素都是对象,如String,那么数组变成集合后,数组中的元素就直接转成 集合中的元素
19、数组变集合以及集合变数组的对比: (1)数组变集合: 方法:static
20、Collections类和Arrays类的使用。(重点) A:Collections 排序 二分查找 发转 B:Arrays 把数组变成字符串输出 排序 二分查找 21、System: (1)描述系统信息的类 (2)该类没有构造方法,该类的方法和属性都是静态的 (3)字段摘要: static InputStream in “标准”输入流。 static PrintStream out “标准”输出流。 (4)方法摘要: static void exit(int status) 终止当前正在运行的 Java 虚拟机。 static void gc() 运行垃圾回收器。 static Properties getProperties() 确定当前的系统属性 static String getProperty(String key) 获取指定键指示的系统属性。 static String getProperty(String key, String def) 获取用指定键描述的系统属性。 static void setIn(InputStream in) 重新分配“标准”输入流。 static void setOut(PrintStream out) 重新分配“标准”输出流。 static void setProperties(Properties props) 将系统属性设置为 Properties 参数。 static String setProperty(String key, String value) 设置指定键指示的系统属性。 22、Runtime: (1)每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。
一、基础知识:
1、JVM、JRE和JDK的区别: JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性。 java语言是跨平台,jvm不是跨平台的。 JRE(Java Runtime Environment):java的运行环境,包括jvm+java的核心类库。 JDK(Java Development Kit):java的开发工具,包括jre+开发工具 2、环境变量path和classpath的作用是什么? (1)path是配置Windows可执行文件的搜索路径,即扩展名为.exe的程序文件所在的目录, 用于指定DOS窗口命令的路径。 (2)Classpath是配置class文件所在的目录,用于指定类搜索路径,JVM就是通过它来寻找该类的class类文件的。
3、变量有什么用?为什么要定义变量?什么时候用? 答:变量的作用:用来存储数据。 为什么要定义变量:用来不断的存放同一类型的常量,并可以重复使用 4、&和&&的区别? 答:(1)&&会出现短路,如果可以通过第一个表达式判断出整个表达式的结果,则不继续后面表达式的运算; 只能操作boolean类型数据; (2)&不会出现短路,将整个表达式都运算。既可以操作boolean数据还可以操作数。
5、标示符命名规则: 由数字(0-9),大小写英文字母,以及_和$组成。 不能以数字开头。 不能使用关键字来自定义命名。 6、数据类型: (1)基本数据类型(4类8种): 整数类型:byte、short、int、long 浮点数类型:float、double 字符类型:char 布尔类型:boolean(ture false) (2)引用数据类型: 类 接口 数组 7、类型转换 精度从高到低 double float long int short(char) byte (1)自动类型转换 将一个低精度---?高精度 (2)强制类型转换 将一个高精度---?低精度(精度会下降) 8、java语言的三种技术架构 J2EE:企业版 是为开发企业环境下的应用程序提供的一套解决方案。 该技术体系中包含的技术如 Servlet、Jsp等,主要针对于Web应用程序开发。 J2SE:标准版
是为开发普通桌面和商务应用程序提供的解决方案。 该技术体系是其他两者的基础,可以完成一些桌面应用程序的开发。 比如Java版的扫雷。 J2ME:小型版 是为开发电子消费产品和嵌入式设备提供的解决方案。 该技术体系主要应用于小型电子消费类产品,如手机中的应用程序等。 9、java的跨平台性: 通过Java语言编写的应用程序在不同的系统平台上都可以运行。 跨平台的原因: 只要在需要运行java应用程序的操作系统上,先安装一个Java虚拟机(JVM Java Virtual Machine)即可。 由JVM来负责Java程序在该系统中的运行。 10、有符号数据的表示法(次重点) 原码,反码(原码取反),补码(反码+1)。 11、函数 定义:函数就是定义在类中的具有特定功能的一段独立小程序。 特点: 定义函数可以将功能代码进行封装 便于对该功能进行复用 函数只有被调用才会被执行 函数的出现提高了代码的复用性 对于函数没有具体返回值的情况,返回值类型用关键字void表示, 那么该函数中的return语句如果在最后一行可以省略不写。 函数的应用两个明确: 明确要定义的功能最后的结果是什么? 明确在定义该功能的过程中,是否需要未知内容参与运算 12、重载: 概念:在同一个类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可。 特点:与返回值类型无关,只看参数列表(参数类型以及参数个数)。 好处:方便于阅读,优化了程序设计。 13、数组: 概念:同一种数据类型的集合。 好处:可以自动给数组中的元素从0开始编号,方便操作这些元素。 14、内存结构: 栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放。 堆内存:数组和对象,通过new建立的实例都存放在堆内存中。 方法区:静态成员、构造函数、常量池、线程池 本地方法区:window系统占用 寄存器:
二、面向对象
1、面向对象思想:
(1)概述:面向对象是相对于面向过程而言的,面向过程强调的是功能,面向对象强调的是将功能封装进对象, 强调具备功能的对象; (2)思想特点: A:是符合人们思考习惯的一种思想; B:将复杂的事情简单化了; C:将程序员从执行者变成了指挥者; 比如我要达到某种结果,我就寻找能帮我达到该结果的功能的对象,如我要洗衣服我就买洗衣机, 至于怎么洗我不管。 (3)特征: 封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式 继承: 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义 这些属性和行为,只要继承那个类即可。 多态: 一个对象在程序不同运行时刻代表的多种状态,父类或者接口的引用指向子类对象
2、类和对象: 类:对现实世界中某类事物的描述,是抽象的,概念上的定义。 对象:事物具体存在的个体。 3:成员变量和局部变量的区别(重点) (1)作用域 成员变量:针对整个类有效。 局部变量:只在某个范围内有效。(一般指的就是方法,语句体内) (2)存储位置 成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。 局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。 当方法调用完,或者语句结束后,就自动释放。 (3)初始值 成员变量:有默认初始值。 局部变量:没有默认初始值,使用前必须赋值。 4、匿名对象 (1)匿名对象就是没有名字的对象。是对象的一种简写形式。 (2)应用场景 A:只调用一次类中的方法。 B:可以作为实际参数在方法传递中使用 5、封装: 指隐藏对象的属性和实现细节,仅对外提供公共访问方式;比如电脑机箱、笔记本等 好处: 将变化隔离; 方便使用; 提高复用性; 提高安全性
6、关键字private:封装在代码中的体现 (1)私有的意思,权限修饰符 (2)用来修饰成员变量和成员函数 (3)用private修饰的成员只在本类中有效 (4)私有是封装的一种体现 7、构造方法: (1)特点: 方法名与类名相同 没有返回类型 没有返回值 (2)作用:构造函数是用于创建对象,并对其进行初始化赋值,对象一建立就自动调用相对应的构造函数, (3)构造方法的注意事项: A:如果一个自定义类没有构造方法,系统会默认给出一个无参构造方法。 B:如果一个自定义类提供了构造方法,那么,系统将不再给出无参构造方法。 这个时候,你可以不使用无参构造方法。 如果你想使用,那么,就必须手动给出无参构造方法。 建议:一般情况下,我们的自定义类都要手动给出无参构造方法。 (4)构造方法和成员方法的区别 A:格式区别 构造方法和类名相同,并且没有返回类型,也没有返回值。 普通成员方法可以任意起名,必须有返回类型,可以没有返回值。 B:作用区别 构造方法用于创建对象,并进行初始化值。 普通成员方法是用于完成特定功能的。 C:调用区别 构造方法是在创建对象时被调用的,一个对象建立,只调用一次相应构造函数 普通成员方法是由创建好的对象调用,可以调用多次 8、构造代码块: (1)作用:给对象进行初始化,对象一建立就执行,而且优先于构造函数执行 (2)构造代码块和构造函数的区别: 构造代码块是给所有不同对象的共性进行统一初始化 构造函数是给对应的对象进行初始化 9、this关键字 (1)this关键字代表本类对象的一个引用,谁调用this所在的方法,this就代表谁 (2)this的使用场景 A:用于区分同名成员变量和局部变量; B:在定义函数时,该函数内部要用到调用该函数的对象时,因为此时对象还没建立,故this代表此对象 B:构造函数间调用 **这个时候,this(参数)必须作为第一条语句存在。 10、Person p = new Person();在内存中做了哪些事情。 (1)将Person.class文件加载进内存中。
(2)如果p定义在主方法中,那么,就会在栈空间开辟一个变量空间p。 (3)在堆内存给对象分配空间。 (4)对对象中的成员进行默认初始化。 (5)对对象中的成员进行显示初始化。 (6)调用构造代码块对对象进行初始化。(如果没有就不执行) (7)调用构造方法对对象进行初始化。对象初始化完毕。 (8)将对象的内存地址赋值给p变量,让p变量指向该对象。 11、static关键字: (1)静态的意思,用来修饰成员变量和成员函数 (2)静态的特点: 随着类的加载而加载 优先于对象存在 对所有对象共享 可以被类名直接调用 (3)静态的注意事项 A:静态方法只能访问静态成员 为什么:因为静态的内容是随着类的加载而加载,它是先进内存的。 B:静态方法中不能使用this,super关键字 C:主方法是静态的 public static void main(String[] args) public:公共的意思,是最大权限修饰符。 static:由于jvm调用main方法的时候,没有创建对象。 只能通过类名调用。所以,main必须用static修饰。 void:由于main方法是被jvm调用,不需要返回值。用void修饰。 main:main是主要的意思,所以jvm采用了这个名字。是程序的入口。 String[]:字符串数组 args:数组名 在运行的时候,通过java命令给args数组赋值。 格式:java MainTest hello world itcast (4)静态变量和成员变量的区别 A:调用方式 静态变量也称为类变量,可以直接通过类名调用。也可以通过对象名调用。 这个变量属于类。 成员变量也称为实例变量,只能通过对象名调用。这个变量属于对象。 B:存储位置 静态变量存储在方法区长中的静态区。 成员变量存储在堆内存。 C:生命周期 静态变量随着类的加载而存在,随着类的消失而消失。生命周期长。 成员变量随着对象的创建而存在,随着对象的消失而消失。 D:与对象的相关性 静态变量是所有对象共享的数据。
|--->删除: void clear(): 移除此列表中的所有元素。 E remove(int index): 移除此列表中指定位置上的元素。 boolean remove(Object o): 移除此列表中首次出现的指定元素(如果存在)。 protected void removeRange(int fromIndex, int toIndex): 移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。 boolean removeAll(Collection> c): 从列表中移除指定 collection 中包含的其所有元素 |--->获取: E get(int index): 返回此列表中指定位置上的元素。 int indexOf(Object o): 返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。 int lastIndexOf(Object o) 返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。 public List
Vector(): 构造一个空向量,使其内部数据数组的大小为 10,其标准容量增量为零。 Vector(Collection extends E> c): 构造一个包含指定 collection 中的元素的向量, 这些元素按其 collection 的迭代器返回元素的顺序排列。 |--->方法摘要: |--->添加: boolean add(E e): 将指定元素添加到此向量的末尾。 void add(int index, E element): 在此向量的指定位置插入指定的元素。 boolean addAll(Collection extends E> c): 将指定 Collection 中的所有元素添加到此向量的末尾, 按照指定 collection 的迭代器所返回的顺序添加这些元素。 boolean addAll(int index, Collection extends E> c): 在指定位置将指定 Collection 中的所有元素插入到此向量中。 |--->获取: Enumeration
(1)HashSet:它不保证set的迭代顺序;特别是它不保证该顺序恒久不变.此类允许使用null元素。 |--->构造方法: HashSet() 构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。 HashSet(Collection extends E> c) 构造一个包含指定 collection 中的元素的新 set。 |--->方法摘要: boolean add(E e) 如果此 set 中尚未包含指定元素,则添加指定元素。 void clear() 从此 set 中移除所有元素。 Object clone() 返回此 HashSet 实例的浅表副本:并没有复制这些元素本身。 boolean contains(Object o) 如果此 set 包含指定元素,则返回 true。 boolean isEmpty() 如果此 set 不包含任何元素,则返回 true。 Iterator
(2)TreeSet:使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序. |--->构造方法:
TreeSet() 构造一个新的空 set,该set根据其元素的自然顺序进行排序。 TreeSet(Collection extends E> c) 构造一个包含指定 collection 元素的新 TreeSet,它按照其元素的自然顺序进行排序。 TreeSet(Comparator super E> comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。 |--->方法摘要: 添加: boolean add(E e) 将指定的元素添加到此 set(如果该元素尚未存在于 set 中)。 boolean addAll(Collection extends E> c) 将指定 collection 中的所有元素添加到此 set 中。 删除: void clear() 移除此 set 中的所有元素。 boolean remove(Object o) 将指定的元素从 set 中移除(如果该元素存在于此 set 中)。 E pollFirst() 获取并移除第一个(最低)元素;如果此 set 为空,则返回 null。 E pollLast() 获取并移除最后一个(最高)元素;如果此 set 为空,则返回 null。 获取: Iterator
**Map:将键映射到值的对象。Map集合没有迭代器!Map集合特点:该集合存储键值对。而且键是唯一的。 |--->方法摘要: |--->添加: V put(K key, V value) 将指定的值与此映射中的指定键关联(可选操作)。 void putAll(Map extends K,? extends V> m) 从指定映射中将所有映射关系复制到此映射中 |--->删除:
void clear() 从此映射中移除所有映射关系(可选操作)。 V remove(Object key) 如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。 |--->判断 boolean containsKey(Object key) 如果此映射包含指定键的映射关系,则返回 true。
boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true。
boolean isEmpty() 如果此映射未包含键-值映射关系,则返回 true。 |--->获取 int size() 返回此映射中的键-值映射关系数。
Collection
重点:Map集合没有迭代器,以下是Map的两种取出方式: 第一种:Set
(3)迭代器方法: boolean hasNext() 如果仍有元素可以迭代,则返回 true。 E next() 返回迭代的下一个元素。 void remove() 从迭代器指向的collection中移除迭代器返回的最后一个元素(可选操作)。
9、列表迭代器:ListIterator (1)List集合特有的迭代器ListIterator是Iterator的子接口,在迭代时,不可以通过集合对象的 方法操作集合中的元素,因为会发生ConcurrentModificationException(当方法检测到对象的并发修改, 但不允许这种修改时,抛出此异常) (2)Iterator方法有限,只能对元素进行判断、取出和删除的操作 ListIterator可以对元素进行添加和修改动作等。 (3)获取列表迭代器方法: ListIterator
以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式。 static int Integer.parseInt(String s) 将字符串参数作为有符号的十进制整数进行解析, 字符串必须是int型范围内的数字字符串 static int Integer.parseInt(String s,int basic) 使用第二个参数指定的基数,将字符串参数解析为有符号的整数. 字符串必须是int型范围内的数字字符串 short shortValue() 以short类型返回该Integer的值。 int intValue() 以int类型返回该Integer的值。 static Integer valueOf(int num) 返回一个表示指定的 int 值的 Integer 实例。 static Integer valueOf(String s) 返回保存指定的String的值的Integer对象。 static Integer valueOf(String s, int radix) 返回一个Integer对象,该对象中保存了用第二个参数提供的基数进行 解析时从指定的String中提取的值。 (6)类型转换 int -- Integer int num = 20; A:Integer i = new Integer(num); B:Integer i = Integer.valueOf(num); Integer -- int Integer i = new Integer(20); A:int num = i.intValue(); int -- String int num = 20; A:String s = String.valueOf(num); B:String s = \ C:String s = Integer.toString(num); String -- int String s = \ A:int num = Integer.parseInt(s); B:Integer i = new Integer(s);或者Integer i = Integer.valueOf(s); int num = i.intValue(); 6、集合框架: (1)为什么出现集合类? 面向对象对事物的体现都是以对象的形式,为了方便对多个对象的操作,就对对象进行存储。 集合就是存储对象最常用的一种方式. (2)数组和集合都是容器,两者有何不同? **数组长度固定,而集合长度是可变的 **数组值可以存储对象,还可以存储基本数据类型;而集合只能存储对象 **数组存储数据类型是固定的,而集合存储的数据类型不固定 (3)集合类的特点: 集合只能存储对象
集合的长度是可变的 集合可以存储不同类型的对象 (4)集合类框架(重要!!!要分清几种容器间的区别): **Collection:顶层接口 |--->List:列表,元素是有序的(元素带角标索引),可以有重复元素,可以有null元素。 |--->ArrayList(JDK1.2):底层的数据结构是数组数据结构,特点是查询速度快(因为带角标), 但是增删速度稍慢,因为当元素多时,增删一个元素则所有元素的角标都得改变 线程不同步。默认长度是10,当超过长度时,按50%延长集合长度。 |--->LinkedList(JDK1.2):底层数据结构式链表数据结构(即后面一个元素记录前一个), 特点:查询速度慢,因为每个元素只知道前面一个元素,但增删速度快 因为元素再多,增删一个,只要让其前后的元素重新相连即可 线程是不同步的。 |--->Vector(JDK1.0):底层数据结构是数组数据结构.特点是查询和增删速度都很慢。 默认长度是10,当超过长度时,按100%延长集合长度。 线程同步。 (Vector功能跟ArrayList功能一模一样,已被ArrayList替代) **List使用注意! |--->ArrayList: (1)当往ArrayList里面存入元素没什么要求时,即只要求有序就行时; (2)当往ArrayList里面存入元素要求不重复时,比如存入学生对象,当同名同姓时 视为同一个人,则不往里面存储。则定义学生对象时,需复写equals方法 public boolean equals(Object obj) { if(!(obj instanceof Student)) return false; Student stu = (Student)obj; return this.name.equals(stu.name)&&this.age==stu.age; } 则往ArrayList集合通过add存入学生对象时,集合底层自己会调用学生类的equals方法, 判断重复学生则不存入。 注:对于List集合,无论是add、contains、还是remove方法,判断元素是
否相同, 都是通过复写equals方法来判断! |--->LinkedList (1)LinkLedist的特有方法: boolean offerFirst(E e) 在此列表的开头插入指定的元素。 boolean offerLast(E e) 在此列表末尾插入指定的元素。 E peekFirst() 获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。 E peekLast() 获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。 E pollFirst() 获取并移除此列表的第一个元素;如果此列表为空,则返回 null。 E pollLast() 获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。 (2)通过LinkLedist的特有方法,可以实现某些数据特殊方式的存取,比如堆栈和队列。 一般情况下,使用哪种List接口下的实现类呢? 如果要求增删快,考虑使用LinkedList 如果要求查询快,考虑使用ArrayList 如果要求线程安全,考虑使用Vector。 |--->Set:集合,元素是无序的(因为没有索引),元素不可以重复。可以有null元素。 |--->HashSet(JDK1.2):底层数据结构是哈希表、存取速度快、元素唯一、线程不同步。 保证性元素唯一的原理: 先判断元素的hashCode值是否相同,再判断两元素的equals方法是否为true (往HashSet里面存的自定义元素要复写hashCode和equals方法, 以保证元素的唯一性!) |--->TreeSet:底层数据结构式二叉树。可以对Set集合中的元素进行排序。元素有序、线程不同步。 保证元素唯一性的依据:compareTo方法return 0 TreeSet排序的第一种方式:让元素自身具备比较性,比如八种基本数据类型或则字符串, 实现Compareble接口,覆盖compareTo方法, 此方式是元素的自然顺序 TreeSet排序的第一种方式:当元素自身不具备比较性(比如存储学生对象时)或者具备的 比较性不是我们所需要的比较性时(比如想字符串的
长度排序), 此时就需要让集合自身具备自定义的比较性。 那如何让集合自身具备比较性呢?可在集合初始化时, 就让集合具备比较方式。即定义一个类, 实现Comparator接口,覆盖compare方法。 **Set集合使用注意事项: (1)HashSet: 通过new的方式往HashSet里面存的元素的hashCode都不同,但通常我们定义对象, 比如学生对象时,虽然是new的两个学生对象,但是当他们name和age一样时,我们认为是 同一个对象,所以为了保证元素的唯一性,我们通常在往HashSet集合里面存储元素时, 在定义对象的类中通常复写hashCode和equals方法。 public int hashCode() { return name.hashCode()+age*39; } public boolean equals(Object obj) { if(!(obj instanceof Student)) return false; Student stu = (Student)obj; return this.name.equals(stu.name)&&this.age==stu.age; } HashSet是如何保证元素唯一性的呢? **如果两元素的hashCode值不同,则不会调用equals方法 **如果两元素的hashCode值相同,则继续判断equals是否返回true; **hashCode和equals方法虽然定义在自定义对象类里面,但不是我们手动调用 而是往HashSet集合里面存储元素的时候,集合底层自己调用hashCode和equals 它自己拿对象去判断,自己判断两元素是否是同一个元素。 (2)TreeSet: TreeSet要求往里面存的元素具备比较性,否则会报错。 TreeSet排序的第一种方式:让元素自身具备比较性 定义对象类,实现Compareble接口,复写compareTo方法,此方式是元素的自然顺序 class Student implements Comparable {
private String name; private int age; public Student(String name,int age) { this.name=name; this.age=age; } public String getName() { return name; } public int getAge() { return age; } public int compareTo(Object obj) { if(!(obj instanceof Student)) throw new RuntimeException(\不是学生对象!\ Student stu = (Student)obj; int num = this.age-stu.age; if(num==0) return this.name.compareTo(stu.name); return num; } } TreeSet排序的第一种方式:让集合具备比较性 当元素自身不具备比较性(比如存储学生对象时)或者具备的 比较性不是我们所需要的比较性时(比如想字符串的长度排序), 此时就需要让集合自身具备自定义的比较性。 那如何让集合自身具备比较性呢?可在集合初始化时, 就让集合具备比较方式。即定义一个类, 实现Comparator接口,覆盖compare方法。 class StringLengthComparator implements Comparator { public int compare(Object obj1,Object obj2) { String s1 = (String)obj1; String s2 = (String)obj2; int num = new Integer(s1.length()).compareTo(new Integer(s2.length())); if(num==0) return s1.compareTo(s2); return num;
} } class TreeSetTest { public static void main(String[] args) { TreeSet ts = new TreeSet(new StringLengthComparator()); ts.add(\ ts.add(\ ts.add(\ ts.add(\ sop(ts); } } 基本数据类型或字符串对象均实现了Comparable接口,故同种类型基本数据间具备比较性,即自然顺序。 **Map:顶层接口,该集合存储的是键值对,而且键是唯一的,Map和Set很像,Set集合底层就是使用了Map集合。 Map集合没有迭代器,要取出元素必须先将Map集合转换成Set集合才能遍历元素 |--->HashTable(JDK1.0): 底层是哈希表数据结构; 不可以使用null键和null值; 用作键的对象必须实现hashCode和equals方法来保证键的唯一性 线程同步,效率低 |--->HashMap(JDK1.2): 底层是哈希表数据结构; 允许使用null键和null值; 线程不同步,效率高; 保证元素唯一性的: 原理:先判断元素的hashCode值是否相同,再判断两元素的equals方法是否为true (往HashSet里面存的自定义元素要复写hashCode和equals方法, 以保证元素的唯一性!) class Student { private String name; private int age; public Student(String name, int age) { super();
this.name = name; this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int hashCode(){ return name.hashCode()+age*34; } @Override public boolean equals(Object obj){ if(!(obj instanceof Student)) return false; Student stu = (Student)obj; return this.name.equals(stu.name)&&this.age==stu.age; }
public class HashMapDemo1 { public static void main(String[] args) { Map
} } |--->TreeMap(JDK1.0): 底层是二叉树结构; 允许使用null键和null值; 线程不同步; 可以给Map集合中的键进行排序. TreeMap排序的第一种方式:让元素自身具备比较性,比如八种基本数据类型或则字符串, 实现Compareble接口,覆盖compareTo方法, 此方式是元素的自然顺序 TreeMap排序的第一种方式:当元素自身不具备比较性(比如存储学生对象时)或者具备的 比较性不是我们所需要的比较性时(比如想字符串的长度排序), 此时就需要让集合自身具备自定义的比较性。 那如何让集合自身具备比较性呢?可在集合初始化时, 就让集合具备比较方式。即定义一个类, 实现Comparator接口,覆盖compare方法。 class Student implements Comparable
} } public class HashMapDemo1 { public static void main(String[] args) { Map
7、集合类各容器方法:
**接口Collection方法摘要(没有构造方法) a)添加: i. boolean add(E e) j. boolean addAll(Collection c) b)删除:
i. void clear():清空容器 j. boolean remove(Objec object): k. boolean removeAll(Collection c): c)判断: i. boolean contains(Object object):判断是否包含此元素 j. boolean containsAll(Collection c):判断是否包含一堆元素 k. boolean equals(Object object):比较此collection与指定对象是否相等 m. boolean isEmpty():判断是否集合为空 d)获取: h. Iterator iterator():取出 i. int hashCode():返回此collection的哈希值 j. int size():返回此collection中元素的个数 k. boolean retainAll(Collection c):取交集 m. Object toArray():返回此collection中所有元素的数组 n. T[] toArray(T[] a):返回包含此collection中所有元素的数值。 *****List集合子类及其方法 (1)List接口是Collection接口的一个子接口。 (2)List接口中的元素有如下特点(对角标的操作都是特有方法,因为有序): A:元素有序(存储顺序和取出顺序一致) B:元素可以重复 (3)List接口中的特有方法 A:add(int index,Object obj):在指定位置加入元素 B:remove(int index):移除指定位置的元素 C:set(int index,Object obj):修改指定位置的元素 D:get(int index):获取指定位置的元素 E:indexOf(Object obj):获取指定元素的位置 F:subList(int start,int end):从一个大的List中截取一个小的List G:listIterator():返回一个List接口特有的迭代器 (1)、ArrayList:
|--->构造方法摘要:(少用,不是重点) ArrayList():构造一个初始容量为 10 的空列表。 ArrayList(Collection extends E> c): 构造一个包含指定 collection 的元素的列表, ArrayList(int initialCapacity): 构造一个具有指定初始容量的空列表。 |--->方法摘要: |--->添加: boolean add(E e): 将指定的元素添加到此列表的尾部。 void add(int index, E element): 将指定的元素插入此列表中的指定位置。 boolean addAll(Collection extends E> c):按照指定 collection 的迭代器所返回的元素顺序, 将该 collection 中的所有元素添加到此列表的尾部 boolean addAll(int index, Collection extends E> c): 从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。