今日学习泛型和Collection中的ArrayList、LinkedList、Vector以及ArrayList与LinkedList两者之间的差别和优缺点
1. 泛型
泛型是将数据类型参数化,即调用时临时声明数据类型,即为广泛的数据类型
- 使用格式:
<想要定义的数据类型>
通过<>来定义要操作的引用数据类型,<>就是用来接受数据类型。
2. 框架简述
- 为什么会出现Collection:在面向对象语言中,数据多了我们可以存到对象里,但是对象多了我们会存到数组里,但是数组操作起来相比较麻烦,而且数组长度是固定的;这时就出现了能够更方便的操作大批量对象的方法:Collection
3. ArrayList
- ArrayList:ArrayList是Collection中的一个常用的实现类,它的结构是一个不固定长度的数组,其默认长度是10,当加入的元素要超过当前ArrayList的长度,ArrayList会自动扩充为原先长度的1.5倍,ArrayList类是在java.util包下,使用前记得引包。
- ArrayList中常用的方法:
ArrayList list = new ArrayList(); //1.增(添加数据) list.add("sad");//在***尾部添加元素,若数组长度不够,需要扩容后添加数据 list.add(0, "aaa");//根据下标插入数据 //2.删(删除数据) list.remove(0);//删除下标0位置上的元素 list.remove("s");//删除指定元素,如果有就删除,如果没有返回false list.clear();//清空***中所有元素 //3.改(修改数据) list.set(0, "asd0");//根据下标修改数据 //4.查(查询数据) list.size();//查询数组的实际长度(里面存了多少数据) list.get(0);//查询下标0的数据 list.indexOf("aaa");//查找第一次出现aaa的下标位置,若查询不到返回-1 list.lastIndexOf("aaa");//查找最后一次出现aaa的下标位置(倒序查找),若查询不到返回-1 list.isEmpty();//查询***长度是否为空,为空返回true,否则返回false list.contains("aa");//查询***中是否有此元素,有返回true,无返回false
4. LinkedList
- LinkedList:LinkedList是Collection中的一个常用的实现类,它的结构类似与C语言中的链表,它的存储空间是不成块的(相对ArrayList来说),每个数据分为三部分:上节点、数据、下节点。上节点存的是上个数据的地址值,下节点存放的是下个数据的地址值,第一个数据没有上节点,最后一个数据没有下节点。LinkedList类是在java.util包下,使用前记得引包。
- LinkedList中常用的方法:
LinkedList list = new LinkedList(); //1.增(添加数据) list.add("sad");//在***尾部添加元素 list.add(0, "aaa");//根据下标插入数据 list.addFirst("aaa");//将aaa添加到***的首部 list.addLast("aaa");//将aaa添加到***的尾部 list.offer("aaa");//将aaa添加到***的尾部 list.offerFirst("aaa");//将aaa添加到***的首部 list.push("aaa");//将aaa添加到***的首部 list.offerLast("aaa");//将aaa添加到***的尾部 //2.删(删除数据) list.remove();//删除***中第一个元素,若***为空则报错 list.remove(0);//删除下标0位置上的元素 list.remove("s");//删除指定元素,如果有就删除,如果没有返回false list.clear();//清空***中所有元素 list.removeFirst();//移除并返回此列表的第一个元素。 list.removeFirstOccurrence("aaa");//删除此列表中第一次出现的指定元素(从头部到尾部遍历列表时),如果***中不包含该元素,则不作更改。 list.removeLast();//移除并返回此列表的最后一个元素。 list.removeLastOccurrence("aaa");//删除此列表中最后一次出现的指定元素(从头部到尾部遍历列表时),如果***中不包含该元素,则不作更改。 //3.改(修改数据) list.set(0, "asd0");//根据下标修改数据 //4.查(查询数据) list.size();//查询数组的实际长度(里面存了多少数据) list.get(0);//查询下标0的数据 list.getFirst();//查询列表的第一个元素 list.getLast();//查列列表的最后一个元素 list.indexOf("aaa");//查找第一次出现aaa的下标位置,若查询不到返回-1 list.lastIndexOf("aaa");//查找最后一次出现aaa的下标位置(倒序查找),若查询不到返回-1 list.peek();//获取但不移除此列表的头(第一个元素)。 list.peekFirst();//获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。 list.peekLast();//获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。 list.poll();//获取并移除此列表的头(第一个元素) list.pollFirst();//获取并移除此列表的第一个元素;如果此列表为空,则返回 null。 list.pollLast();//获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。 list.pop();//移除并返回此列表的第一个元素。 list.isEmpty();//查询***长度是否为空,为空返回true,否则返回false list.contains("aa");//查询***中是否有此元素,有返回true,无返回false
5. Vector
- Vector:Vector是Collection中较早的一种实现类,它的结构和方法基本与ArrayList相同,但是Vector扩容时是2倍扩容,而ArrayList是1.5倍扩容,节省了空间,但是Vector中添加了资源锁,执行效率就会比ArrayList满上很多,所以在以后的开发中Vector使用的较少,更多的时候是使用ArrayList
6. ArrayList与LinkedList的优缺点比较
- 增(添加数据):
在添加数据时要考虑数据的寻址问题,即考虑寻找 “数据添加的位置” 的代价 数组寻址:首地址+下标*间隔 链表寻址:用首节点.下一个节点.下一个节点。下一个节点.….直到找到想要的位置。 即:LinkedList在首尾寻址极快,中间部分ArrayList较快 ArrayList LinkedList 数据的首部:插入代价高,全部移动 插入代价低(首尾更低) 数据的中间:插入代价中,移动一半 插入代价低 数据的尾部:插入代价极低或极高(扩容与否) 插入代价低 综合(两者比较): 前 链表较快,数组极慢 中 链表较快,数组较慢 末 链表较慢,数组较快(数组扩容时极慢)
- 删(删除数据):
在删除数据时要考虑数据的寻址问题,即考虑寻找 “数据添加的位置” 的代价 数组寻址:首地址+下标*间隔 链表寻址:用首节点.下一个节点.下一个节点。下一个节点.….直到找到想要的位置。 即:LinkedList在首尾寻址较快,中间部分ArrayList较快 ArrayList LinkedList 数据的首部:删除代价高,全部移动 删除代价低 数据的中间:删除代价中,移动一半 删除代价低 数据的尾部:删除代价极低 删除代价低 综合(两者比较): 前 链表较快 中 基本相同 末 数组较快
- 改(修改数据):
在修改数据时要考虑数据的寻址问题,即考虑寻找 “数据添加的位置” 的代价 数组寻址:首地址+下标*间隔 链表寻址:用首节点.下一个节点.下一个节点。下一个节点.….直到找到想要的位置。 即:LinkedList在首尾寻址较快,中间部分ArrayList较快 ArrayList LinkedList 数据的首部:基本相同 数据的中间:基本相同 数据的尾部:基本相同 综合(两者比较): 前 基本相同 中 链表较数组慢,因为寻址的慢 末 基本相同
- 查(查询数据):
在查询数据时 只需要 考虑数据的寻址问题,即考虑寻找 “数据添加的位置” 的代价 数组寻址:首地址+下标*间隔 链表寻址:用首节点.下一个节点.下一个节点。下一个节点.….直到找到想要的位置。 即:LinkedList在首尾寻址极快,中间部分ArrayList较快 综合: 前 链表较快 中 数组较快 末 链表较快