一、List接口
1、添加
① add(int index, E element)
② addAll(int index, Collection c)
2、获取
① get(int index)
② indexOf(Object o)
③ lastIndexOf(Object o)
④ subList(int fromIndex, int toIndex)
3、修改:set(int index, E element)
4、迭代:listIterator()
import java.util.ArrayList;
import java.util.List;
public class Demo21.1{
public static void main(String[] args) {
List list = new ArrayList();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("张三");
list.add("李四");
System.out.println("集合的元素:"+ list);
}
}
5、List接口中特有的方法具备的特点: 操作的方法都存在索引值。
只有List接口下面的集合类才具备索引值,其他接口下面的集合类都没有索引值。
import java.util.ArrayList;
import java.util.List;
public class Demo21.2{
public static void main(String[] args) {
List list = new ArrayList();
list.add("狗娃");
list.add("狗剩");
list.add("铁蛋"); //把元素添加到集合的末尾处
list.add(1, "赵本山"); //把元素添加到集合中的指定索引值位置上
List list2 = new ArrayList();
list2.add("本山");
list2.add("小沈阳");
list.addAll(2,list2); //把list2的元素添加到list集合指定索引值的位置上
System.out.println("get方法获取元素:"+list.get(1)); //根据索引值获取集合中的元素
//使用get方法遍历集合的元素:
for (int i = 0; i < list.size() ; i++) {
System.out.print(list.get(i)+",");
}
System.out.println("找出指定元素第一次出现在集合中的索引值:"+ list.indexOf("本山"));
System.out.println("找指定的元素最后一次出现在集合中的索引值:"+list.lastIndexOf("狗娃"));
List subList = list.subList(1, 3); //指定开始与结束的索引值截取集合中的元素。
System.out.println("子集合的元素是:"+ subList);
list.set(3, "赵本山"); //使用指定的元素替换指定索引值位置的元素
System.out.println("集合的元素:"+list);
}
}
二、ListIterator接口
1、ListIterator接口特有的方法
① hasPrevious():判断是否存在上一个元素。
② previous():当前指针先向上移动一个单位,然后再取出当前指针指向的元素。
③ next():先取出当前指针指向的元素,然后指针向下移动一个单位。
④ add(E e):把当前有元素插入到当前指针指向的位置上。
⑤ set(E e):替换迭代器最后一次返回的元素。
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Demo21.3{
public static void main(String[] args) {
List list = new ArrayList();
list.add("狗娃");
list.add("狗剩");
list.add("铁蛋");
list.add("美美");
ListIterator it = list.listIterator(); //返回的是一个List接口中特有的迭代器
System.out.println("有上一个元素吗?"+ it.hasPrevious());
System.out.println("获取上一个元素:"+it.previous());
it.next();
System.out.println("获取上一个元素:"+ it.previous());
while(it.hasNext()){
it.next();
}
while(it.hasPrevious()){
System.out.println("元素:"+ it.previous());
}
it.next();
it.next();
it.add("张三");
it.next();
it.next();
it.set("张三");
System.out.println("集合的元素:"+ list);
}
}
2、练习: 使用三种方式遍历集合的元素
第一种: 使用get方法遍历。
第二种: 使用迭代器正序遍历。
第三种: 使用迭代器逆序遍历。
import java.util.List;
import java.util.ArrayList;
import java.util.ListIterator;
public class Demo21.4{
public static void main(String[] args) {
List list = new ArrayList();
list.add("张三");
list.add("李四");
list.add("王五");
System.out.println("======get方法遍历=======");
for(int i = 0 ; i<list.size() ; i++){
System.out.print(list.get(i)+",");
}
System.out.println("\r\n======使用迭代器正序遍历==========");
ListIterator it = list.listIterator(); //获取到迭代器
while(it.hasNext()){
System.out.print(it.next()+",");
}
System.out.println("\r\n======使用迭代器逆序遍历==========");
while(it.hasPrevious()){
System.out.print(it.previous()+",");
}
}
}
3、迭代器在变量元素的时候要注意事项
在迭代器迭代元素的过程中,不允许使用集合对象改变集合中的元素个数,如果需要添加或者删除只能使用迭代器的方法进行操作。如果使用过了集合对象改变集合中元素个数那么就会出现ConcurrentModificationException异常
[迭代元素的过程中:迭代器创建到使用结束的时间]
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Demo21.5{
public static void main(String[] args) {
List list = new ArrayList();
list.add("张三");
list.add("李四");
list.add("王五");
ListIterator it = list.listIterator(); //获取到迭代器
while(it.hasNext()){
System.out.print(it.next()+",");
it.add("aa"); //把元素添加到当前指针指向位置
//list.add("aa"); //add方法是把元素添加到集合的末尾处的 > 报错
//list.remove("张三");
}
list.add("aa");
//it.next();
System.out.println("\r\n集合的元素:"+ list);
}
}
三、ArrayList实现类
笔试题目: 使用ArrayList无参的构造函数创建一个对象时, 默认的容量是多少? 如果长度不够使用时又自增增长多少?
答:ArrayList底层是维护了一个Object数组实现的(查询速度快、增删慢),使用无参构造函数时,Object数组默认的容量是10,当长度不够时,自动增长了0.5倍。
如果目前的数据是查询比较多,增删比较少时候,可以使用ArrayList存储数据。
import java.util.ArrayList;
import java.util.Iterator;
class Book{
int id;
String name;// 名字
public Book(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "{ 书号:"+ this.id+" 书名:"+ this.name+" }";
}
@Override
public boolean equals(Object obj) {
Book book =(Book)obj;
return this.id==book.id;
}
}
// 需求:编写一个函数清除集合中重复元素,如果书号是一样就视为重复元素。
// 要求:遍历集合元素的时候必须使用迭代器。get迭代器
public class Demo21.6{
public static void main(String[] args) {
ArrayList list= new ArrayList();
list.add(new Book(110,"java编程思想"));
list.add(new Book(220,"java核心技术"));
list.add(new Book(330,"深入javaweb"));
list.add(new Book(110,"javas神书"));
ArrayList list2 = clearRepeat(list);
System.out.println("新集合的元素是:"+ list2);
}
public static ArrayList clearRepeat(ArrayList list){
//创建一个新的集合
ArrayList newList = new ArrayList();
//获取迭代器
Iterator it = list.iterator();
while(it.hasNext()){
Book book = (Book) it.next(); //从旧集合中获取的元素
if(!newList.contains(book)){
//如果新集合没有包含该书籍,那么就存储到新集合中
newList.add(book);
}
}
return newList;
}
}
四、Linkedlist实现类
1、方法介绍
Linkedlist底层是使用了链表数据结构实现的(查询速度慢、增删快)
① addFirst(E e)
② addLast(E e)
③ getFirst()
④ getLast()
⑤ removeFirst()
⑥ removeLast()
2、数据结构
① 栈 (1.6):主要是用于实现堆栈数据结构的存储方式。
先进后出:push()、pop()
② 队列(双端队列1.5): 主要是为了让你们可以使用LinkedList模拟队列数据结构的存储方式。
先进先出:offer()、poll()
③ 返回逆序的迭代器对象
descendingIterator():返回逆序的迭代器对象
import java.util.LinkedList;
public class Demo21.7{
public static void main(String[] args) {
LinkedList list= new LinkedList();
list.add("张三");
list.add("李四");
list.add("王五");
list.addFirst("狗娃"); //把元素添加到集合的首位置上。
list.addLast("狗剩"); //把元素添加到集合的末尾处。
System.out.println("获取集合中首位置的元素:"+list.getFirst());
System.out.println("获取集合中末尾的元素:"+ list.getLast());
System.out.println("删除集合中的首位置元素并返回:"+ list.removeFirst());
System.out.println("删除集合中的末尾素并返回:"+ list.removeLast());
list.push("狗娃"); //将该元素插入此集合的开头处。
System.out.println("删除集合的首元素:"+list.pop()); // 移除并返回集合中的第一个元素
list.offer("狗剩");
System.out.println("删除集合的首元素: "+list.poll());
System.out.println("集合中的元素:"+ list);
Iterator it = list.descendingIterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
3、机试题目: 使用LinkedList实现堆栈数据结构的存储方式与队列的数据结构存储方式。
import java.util.LinkedList;
import java.util.Random;
// 使用LinkedList模拟堆栈的数据结构存储方式
class StackList{
LinkedList list;
public StackList(){
list = new LinkedList();
}
//进栈
public void add(Object o){
list.push(o);
}
//弹栈 : 把元素删除并返回。
public Object pop(){
return list.pop();
}
//获取元素个数
public int size(){
return list.size();
}
}
//使用LinkedList模拟队列的存储方式
class TeamList{
LinkedList list;
public TeamList(){
list = new LinkedList();
}
public void add(Object o){
list.offer(o);
}
public Object remove(){
return list.poll();
}
//获取元素个数
public int size(){
return list.size();
}
}
public class Demo21.8{
public static void main(String[] args) {
TeamList list= new TeamList();
list.add("张三");
list.add("李四");
list.add("王五");
int size = list.size();
for(int i = 0 ; i<size ; i++){
System.out.println(list.remove());
}
}
}
4、需求: 使用LinkedList存储一副扑克牌,然后实现洗牌功能。
//扑克类
class Poker{
String color; //花色
String num; //点数
public Poker(String color, String num) {
super();
this.color = color;
this.num = num;
}
@Override
public String toString() {
return "{"+color+num+"}";
}
}
public class Demo21.9 {
public static void main(String[] args) {
LinkedList pokers = createPoker();
shufflePoker(pokers);
showPoker(pokers);
}
//洗牌的功能
public static void shufflePoker(LinkedList pokers){
//创建随机数对象
Random random = new Random();
for(int i = 0 ; i <100; i++){
//随机产生两个索引值
int index1 = random.nextInt(pokers.size());
int index2 = random.nextInt(pokers.size());
//根据索引值取出两张牌,然后交换两张牌的顺序
Poker poker1 = (Poker) pokers.get(index1);
Poker poker2 = (Poker) pokers.get(index2);
pokers.set(index1, poker2);
pokers.set(index2, poker1);
}
}
//显示扑克牌
public static void showPoker(LinkedList pokers){
for(int i = 0 ; i<pokers.size() ; i++){
System.out.print(pokers.get(i));
//换行
if(i%10==9){
System.out.println();
}
}
}
//生成扑克牌的方法
public static LinkedList createPoker(){
//该集合用于存储扑克对象。
LinkedList list = new LinkedList();
//定义数组存储所有的花色与点数
String[] colors = {"黑桃","红桃","梅花","方块"};
String[] nums = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
for(int i = 0 ; i < nums.length ; i++){
for(int j = 0 ; j<colors.length ; j++){
list.add(new Poker(colors[j], nums[i]));
}
}
return list;
}
}
5、
import java.util.LinkedList;
class Person{
String name;
int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "{ 名字:"+ this.name+" 年龄:"+ this.age+"}";
}
}
public class Demo21.10{
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.add(new Person("狗娃", 7));
list.add(new Person("狗剩", 17));
list.add(new Person("铁蛋", 3));
list.add(new Person("美美", 30));
//编写一个函数根据人的年龄及逆行排序存储。
for(int i= 0 ; i<list.size() -1 ; i++){
for(int j = i+1 ; j<list.size() ; j++){
//符合条件交换位置
Person p1 = (Person) list.get(i);
Person p2 = (Person) list.get(j);
if(p1.age>p2.age){
//交换位置
list.set(i, p2);
list.set(j, p1);
}
}
}
System.out.println(list);
}
}
五、Vector实现类(了解即可)
1、底层也是维护了一个Object的数组实现的,实现与ArrayList是一样的,但是Vector是线程安全的,操作效率低。
2、笔试题
说出ArrayLsit与Vector的区别?
相同点: ArrayList与Vector底层都是使用了Object数组实现的。
不同点: ArrayList是线程不同步的,操作效率高; Vector是线程同步的,操作效率低。ArrayList是JDK1.2出现;Vector是jdk1.0的时候出现的。
public class Demo21.11{
public static void main(String[] args) {
Vector v = new Vector();
//添加元素
v.addElement("张三");
v.addElement("李四");
v.addElement("王五");
//迭代该集合
Enumeration e = v.elements(); //获取迭代器
while(e.hasMoreElements()){
System.out.println(e.nextElement());
}
}
}