一、Math
1、两个常量:
(1)E:自然对数的底数,2.718
(2)PI:圆周率,3.141592653589793
2、常用方法:
(1)abs(数字类型) 求绝对值
(2)cbrt(double d) 开立方
(3)sqrt(double d) 开平方
(4)ceil(double d) 向上取整
(5)floor(double d) 向下取整
(6)max(int a, int b) 求最大值
(7)min(int a, int b) 求最小值
(8)pow(int a, int b) 求a的b次方
(9)random() 返回[0.0, 1.0)的随机数
(10)round(double d) 四舍五入,负数部分可以看成”五舍六入”
二、集合概述
(一)对象类型的数组
1、定义一个数组,里面存储的都是某个类型的对象,对象是引用数据类型,所以数组中存储的是这些对象的地址值
2、集合:也是一个类似数组的统一存储、管理数据的容器,**集合只能存储引用数据类型,不能存储基本数据类型,**就好像是对象数组
代码示例
public class Demo02_InstanceArray {
public static void main(String[] args) {
//数组创建在堆内存中
//对象也创建在堆内存中,并且对象具有地址
//数组存储的不再是对象本身,而是对象的地址
Person[] arr = {
new Person("张三", 23),
new Person("李四", 24),
new Person("王五", 25),
new Person("赵六", 26)
};
}
}
(二)集合的由来
1、对象数组的不足:
(1)无法扩展:数组本身长度固定,一旦创建无法更改
(2)结果:每次要添加一个新的元素,都需要创建一个更大的新数组,将原数组的内容填入新数组,并且填入新加入的元素,长此以往非常麻烦。并且这些操作和我们实际开发中的业务逻辑并不相关
(3)所有关于数组操作的业务逻辑都需要自己去定义,并且自己定义的操作还不全面
2、集合的优势:
(1)可扩展:底层会自动增长,不用我们主动操作进行扩展,避免了不必要的麻烦
(2)集合中定义了大量的操作集合的方法,这些方法还十分易用,为我们操作集合提供了便利
(3)集合存储的全是引用数据类型,及对象,也利于我们面向对象编程思想
(4)不带泛型的集合可以存储各种类型的数据
(三)集合和数组的区别
1、共同点:
(1)都是用于存储和管理数据的容器
(2)零散的变量不便于操作和存储,使用一个容器统一管理,容器都具有索引或者类似索引的标志,便于查找和管理数据
2、不同点:
(1)存储内容不同:
1)数组既能够存储基本数据类型,也能够存储引用数据类型
2)集合只能存储引用数据类型,就算添加的时候是基本数据类型,存储在集合中也是基本数据类型包装类的对象
(2)存储的数量不同:
1)数组创建出来后,大小不可变,数组容量有多大,就能存储多少数据
2)集合底层可以自动增长,容量可变
(3)方法不同:
1)数据只能使用Object类型的方法和一个length
2)集合中有大量易用的方法
(四)集合的体系结构
1、集合分类:
(1)单列集合:每个元素都是一个单独的个体,就类似数组一样
(2)双列集合:每个操作都针对一对数据进行,以一对数据为单位
2、单列集合的体系结构:
3、双列集合的体系结构:
三、Collection接口
(一)概述和常用方法
1、Collection,接口名,含义:收集、集合
2、单列集合的顶层接口,定义了所有单列集合共性的功能
3、Collection是接口无法创建对象,所以为了学习,我们先使用实现类ArrayList创建对象,进行功能的使用:接口Collection的引用,指向实现类ArrayList的对象
4、常用方法:
(1)add(Object obj):将obj元素添加到集合中
(2)remove(Object obj) 将obj元素从集合中删除
(3)clear() 清空集合
(4)isEmpty() 判断集合是否为空
(5)contains(Object obj) 判断集合是否包含指定元素
(6)size() 返回集合元素个数
代码示例
import java.util.ArrayList;
import java.util.Collection;
public class Demo03_Collection {
public static void main(String[] args) {
Collection list = new ArrayList();
//System.out.println(list);
list.add("abc");
list.add("abc");
list.add(123);
list.add(123);
list.add(3.5);
list.add(3.5);
list.add(false);
list.add(false);
list.add(true);
System.out.println(list.size());
//System.out.println(list.contains(123));
/*System.out.println(list);
list.remove(true);
System.out.println(list);
list.clear();
System.out.println(list);
System.out.println(list.isEmpty());*/
}
}
(二)Collection的第一种遍历方式
1、toArray() 将集合中的元素添加到一个数组并且返回
2、调用此方法,将集合元素存入数组返回数组,再对数组进行遍历即可
代码示例
import java.util.ArrayList;
import java.util.Collection;
public class Demo04_PrintCollection {
public static void main(String[] args) {
Collection list = new ArrayList();
list.add(123);
list.add(123);
list.add(3.5);
list.add(3.5);
list.add("abc");
list.add("abc");
list.add(false);
list.add(false);
list.add(true);
list.add(true);
list.add('a');
list.add('q');
//1.将集合转为数组
Object[] arr = list.toArray();
//2.遍历数组
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
(三)Collection中带All的方法
1、addAll(Collection list) 将参数几何的元素全部添加到调用者集合中
2、containsAll(Collection list) 判断调用者集合中是否包含参数几何的所有元素,如果是就返回true,否则为false
3、removeAll(Collection list) 从调用者集合中删除和参数几何相同的那些元素
4、retainAll(Collection list) 仅在调用者集合中保留和参数几何重复的元素
代码示例
import java.util.ArrayList;
import java.util.Collection;
public class Demo05_AllMethod {
public static void main(String[] args) {
Collection list1 = new ArrayList();
list1.add("abc");
list1.add("def");
list1.add("ghi");
list1.add("jkl");
list1.add("mno");
list1.add("123");
list1.add("456");
list1.add("789");
list1.add("???");
Collection list2 = new ArrayList();
list2.add("ghi");
list2.add("jkl");
list2.add("mno");
list1.retainAll(list2);
System.out.println(list1);
}
public static void test3() {
Collection list1 = new ArrayList();
list1.add("abc");
list1.add("def");
list1.add("ghi");
list1.add("jkl");
list1.add("mno");
list1.add("123");
list1.add("456");
list1.add("789");
list1.add("???");
Collection list2 = new ArrayList();
list2.add("==");
list1.removeAll(list2);
System.out.println(list1);
}
public static void test2() {
Collection list1 = new ArrayList();
list1.add("abc");
list1.add("def");
list1.add("ghi");
list1.add("jkl");
list1.add("mno");
Collection list2 = new ArrayList();
list2.add("abc");
list2.add("def");
list2.add("ghi");
list2.add("jkl");
list2.add("mno");
System.out.println(list1.containsAll(list2));
}
public static void test1() {
Collection list1 = new ArrayList();
list1.add(123);
list1.add(123);
list1.add(3.5);
list1.add(3.5);
list1.add("abc");
list1.add("abc");
list1.add(false);
list1.add(false);
list1.add(true);
list1.add(true);
list1.add('a');
list1.add('q');
Collection list2 = new ArrayList();
list2.add("@@@");
list2.add("@#$%^&*");
list2.add("*****");
list2.add("!!!!!!!!");
list2.add("+++++++");
System.out.println(list1);
list1.addAll(list2);
System.out.println(list1);
}
}
(四)集合的第二种遍历方式:迭代器
1、迭代:更迭、更新换代,从一个到另一个的过程
2、迭代器:专门用于将集合中的元素,一个到另一个迭代的对象
3、迭代器的获取:集合内部就有一个可以迭代自己的对象,我们直接从集合获取即可
(1)调用iterator()方法,返回一个迭代器对象
4、迭代器的使用:获取到的迭代器是Iterator接口的实现类对象,在迭代器接口中由相应的方法
(1)hasNext() 判断是否有下一个可以迭代的元素,如果有,就返回true
(2)next() 获取集合中的下一个元素
(3)remove() 删除集合中迭代器正在遍历的那个元素
5、迭代器使用的注意事项:
(1)hasNext() 每次只能判断下一个元素是否存在
(2)next() 每次只能获取一个元素并且将迭代器向下一个元素移动一个位置
(3)调用一次hasNext()方法只能调用一次next()方法
(4)如果调用一次hasNext()就调用多次next()会出现NoSuchElementException(没有当前元素异常)
代码示例
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo06_Iterator {
public static void main(String[] args) {
Collection list = new ArrayList();
list.add(new Person("张三", 23));
list.add(new Person("李四", 24));
list.add(new Person("王五", 25));
//list.add(new Person("赵六", 26));
//1.获取当前集合的迭代器对象
Iterator it = list.iterator();
//2.迭代器遍历
while(it.hasNext()) {
Object obj = it.next();
Person p = (Person)obj;
System.out.println(p.getName() + "..." + p.getAge());
//System.out.println(((Person)it.next()).getName() + "..." + ((Person)it.next()).getAge());
}
}
public static void test1() {
Collection list = new ArrayList();
list.add("abc");
list.add("abc");
list.add(123);
list.add(123);
list.add(3.5);
list.add(3.5);
list.add(false);
list.add(false);
list.add(true);
//1.获取迭代器对象:迭代器遍历集合,所有动作由迭代器完成
Iterator it = list.iterator();
//2.调用hasNext()方法判断是否有下一个元素可以迭代
while(it.hasNext()) {
Object obj = it.next();
if("abc".equals(obj)) {
it.remove();
}
}
}
}
四、List接口
(一)概述
1、是Collection的子接口
2、特点:
(1)有序:元素的存储顺序和获取顺序保持一致
(2)可重复:允许存储重复元素
(3)可重复的原因:有索引。因为对于重复的元素,具有不同的索引来区分
3、特有方法:
(1)add(int index, Object obj) 将指定元素插入到集合的指定位置
(2)remove(int index) 删除指定索引上的指定元素
(3)set(int index, Object obj) 用指定元素替换指定索引上原有的元素
(4)get(int index) 返回指定索引上的元素
代码示例
import java.util.ArrayList;
import java.util.List;
public class Demo07_List {
public static void main(String[] args) {
List list = new ArrayList();
list.add("abc");
list.add("abc");
list.add(123);
list.add(123);
list.add(3.5);
list.add(3.5);
list.add(false);
list.add(false);
list.add(true);
System.out.println(list);
//list.add(9, "???");
//list.remove(4);
//list.set(0, "=============");
System.out.println(list.get(list.size() - 1));
System.out.println(list);
}
}
(二)第三种遍历方式
1、针对List集合特有的遍历方式,Collection中不一定能用,Set中一定不能用
2、可以通过size方法获取到集合的长度,进而就能得到List集合的索引范围,再配合get方法,就能获取到每一个索引对应的每一个元素了
代码示例
import java.util.ArrayList;
import java.util.List;
public class Demo08_PrintList {
public static void main(String[] args) {
List list = new ArrayList();
list.add("abc");
list.add("abc");
list.add(123);
list.add(123);
list.add(3.5);
list.add(3.5);
list.add(false);
list.add(false);
list.add(true);
for(int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
(三)并发修改异常
1、ConcurrentModificationException
并发 修改 异常
2、出现原因:在使用迭代器对象遍历集合的时候,通过集合对象操作集合
3、避免方式:
(1)集合遍历集合修改
(2)迭代器遍历迭代器修改
4、List集合特有的迭代器:ListIterator
(1)迭代便利操作:和以前一样
(2)迭代增加:在ListIterator中有add方法,可以向集合中添加元素
(3)ListIterator是Iterator的子接口
(4)在List集合中要调用方法获取这个迭代器,方法:listIterator()
代码示例
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
* 定义一个List集合,在集合中添加若干个元素,
* 其中有一个元素是"def",当遍历集合遇到
* "def"时,向集合中添加元素"666"
*
* @author Zihuatanejo
*
*/
public class Demo09_ConcurrentModificationException {
public static void main(String[] args) {
List list = new ArrayList();
list.add("abc");
list.add("qwe");
list.add("[][]");
list.add("qwe");
list.add("iuo");
list.add("def");
list.add("iuo");
list.add("iuo");
list.add("[][]");
System.out.println(list);
for (int i = 0; i < list.size(); i++) {
Object obj = list.get(i);
if("def".equals(obj)) {
list.add("666");
}
}
/*Iterator it = list.iterator();
while(it.hasNext()) {
Object obj = it.next();
if("def".equals(obj)) {
list.add("666");
}
}*/
/*ListIterator lit = list.listIterator();
while(lit.hasNext()) {
Object obj = lit.next();
if("def".equals(obj)) {
lit.add("666");
}
}*/
System.out.println(list);
}
}
五、List的实现类
(一)概述
1、List是一个接口,无法直接创建对象,所以根据底层实现的不同,具有不同的实现类
2、Vector:数组实现,顺序存储
3、ArrayList:数组实现,顺序存储
4、LinkedList:链表实现,节点存储
(二)Vector
1、在JDK1.0版本出现,这个类已经过时,在JDK1.2被ArrayList取代
2、特点:
(1)线程安全,效率低
(2)顺序存储,增删较慢
3、特有方法:
(1)addElement(Object obj) 向集合中添加元素
(2)removeElement(Object obj) 删除集合中的元素
(3)elements() Vector的枚举对象(迭代器)
4、特有的遍历方式:
(1)使用elements方法获取Enumeration对象
(2)使用获取到的对象调用hasMoreElements方法判断是否有下一个元素
(3)使用获取到的对象调用nextElement方法获取下一个元素
代码示例
import java.util.Enumeration;
import java.util.Vector;
public class Demo10_Vector {
public static void main(String[] args) {
Vector v = new Vector();
v.addElement("abc");
v.addElement("abc");
v.addElement("def");
v.addElement("def");
v.addElement(123);
v.addElement(123);
v.addElement(6.6);
v.addElement(6.6);
v.addElement(6.6);
/*System.out.println(v);
v.removeElement("def");
System.out.println(v);*/
Enumeration e = v.elements();
while(e.hasMoreElements()) {
System.out.println(e.nextElement());
}
}
}
(三)ArrayList
1、也是List接口的一个实现类
2、没有什么特有的方法
3、存储方式:
(1)数组实现,顺序存储
(2)增删慢,查询快
(3)通过物理内存结构实现位置关系,来表达逻辑顺序的相临
(四)LinkedList
1、List接口的实现类
2、存储方式:
(1)节点实现,链式存储
(2)不是通过物理结构实现相临关系,是通过逻辑顺序实现的相临关系
(3)每个节点中,既存储了元素,又存储了相临节点的地址,通过地址实现前后的逻辑顺序
3、图示:
4、特点:
(1)查询速度慢:需要根据前面的节点来获取后一个节点的地址,前面所有的节点都要访问一遍,节点数量越多,查询速度越慢
(2)增删速度快:增加或者删除一个元素,只需要修改相邻接点中的地址即可
5、LinkedList特有的方法:由于底层的特性,专门针对性的提供了在头部尾部增删的操作:
(1)addFirst(Object obj) 将指定元素插入到列表头部
(2)addLast(Object obj) 将指定元素插入到列表尾部
(3)removeFirst() 删除头部元素并且返回
(4)removeLast() 删除尾部元素并且返回
(5)getFirst() 返回头部元素
(6)getLast() 返回尾部元素
代码示例
import java.util.LinkedList;
public class Demo11_LinkedList {
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.addFirst("a");
list.addFirst("b");
list.addFirst("c");
list.addFirst("d");
list.addFirst("e");
System.out.println(list);//edcba
list.addLast("x");
list.addLast("y");
list.addLast("z");
System.out.println(list);
//System.out.println(list.removeFirst());
System.out.println(list.removeLast());
System.out.println(list);
System.out.println(list.getFirst());
System.out.println(list.getLast());
}
}
(五)练习1
比较ArrayList和LinkedList在头部增删的效率
代码示例
import java.util.ArrayList;
import java.util.LinkedList;
//比较ArrayList和LinkedList在头部增删的效率
public class Demo12_Exercise1 {
public static final int NUM = 100000;
public static void main(String[] args) {
/*test1();
test2();*/
test3();
test4();
}
public static void test4() {
LinkedList list = new LinkedList();
for (int i = 1; i <= NUM; i++) {
list.add(i);
}
long start = System.currentTimeMillis();
for (int i = 0; i < NUM; i++) {
list.removeFirst();
}
long end = System.currentTimeMillis();
System.out.println("LinkedList:" + (end - start));
}
public static void test3() {
ArrayList list = new ArrayList();
for (int i = 1; i <= NUM; i++) {
list.add(i);
}
long start = System.currentTimeMillis();
for (int i = 0; i < NUM; i++) {
list.remove(0);
}
long end = System.currentTimeMillis();
System.out.println("ArrayList:" + (end - start));
}
public static void test2() {
LinkedList list = new LinkedList();
long start = System.currentTimeMillis();
for (int i = 1; i <= NUM; i++) {
list.addFirst(i);
}
long end = System.currentTimeMillis();
System.out.println("LinkedList:" + (end - start));
}
public static void test1() {
ArrayList list = new ArrayList();
long start = System.currentTimeMillis();
for (int i = 1; i <= NUM; i++) {
list.add(0, i);
}
long end = System.currentTimeMillis();
System.out.println("ArrayList:" + (end - start));
}
}
(六)练习2
比较ArrayList和LinkedList在查询元素的效率
代码示例
import java.util.ArrayList;
import java.util.LinkedList;
/**
* 比较ArrayList和LinkedList在查询元素的效率
*
* @author Zihuatanejo
*
*/
public class Demo13_Exercise2 {
public static final int NUM = 100000;
public static void main(String[] args) {
test1();
test2();
}
public static void test2() {
LinkedList list = new LinkedList();
for (int i = 1; i <= NUM; i++) {
list.add(i);
}
long start = System.currentTimeMillis();
for (int i = 0; i < NUM; i++) {
list.get(i);
}
long end = System.currentTimeMillis();
System.out.println("LinkedList:" + (end - start));
}
public static void test1() {
ArrayList list = new ArrayList();
for (int i = 1; i <= NUM; i++) {
list.add(i);
}
long start = System.currentTimeMillis();
for (int i = 0; i < NUM; i++) {
list.get(i);
}
long end = System.currentTimeMillis();
System.out.println("ArrayList:" + (end - start));
}
}