第三阶段 JAVA常见对象的学习

集合框架——List接口

image

按照集合框架的继承体系,我们先从Collection中的List接口开始学习

(一) 概述及功能(ArrayList演示)

(1) 概述

List在Collection中充当着一个什么样的身份呢?——有序的 collection(也称为序列)

实现这个接口的用户以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。与 set 不同,列表通常允许重复的元素。

(2)List集合功能

A:基本功能:(继承而来)

//添加功能
boolean add(E e)向集合中添加一个元素//删除功能
void clear():移除集合中的所有元素
boolean remove(Object o):从集合中移除指定的元素
boolean removeAll(Collection<?> c):从集合中移除一个指定的集合元素(有一个就返回true)//获取功能
Iterator iterator():就是用来获取集合中每一个元素。//判断功能
boolean isEmpty():判断集合是否为空
boolean contains(Object o):判断集合中是否包含指定元素
boolean containsAll(Collection<?> c):判断集合中是否包含指定的一个集合中的元素//长度功能
int size():获取集合中元素的个数//集合转换为数组
Object[] toArray()

B:特有功能:


//添加功能:在指定位置添加元素
void add(int index,Object element)//获取功能:获取指定位置的元素
Object get(int index)//列表迭代器:List集合特有的迭代器
ListIterator listIterator()//删除功能:根据索引删除元素,返回被删除的元素
Object remove(int index)//修改功能:根据索引修改元素,返回被修饰的元素。
Object set(int index,Object element)

A:add() 使用方法:

我们还是先写一个List遍历字符串的代码

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class Demo1 {public static void main(String[] args) {//创建集合对象List list = new ArrayList();//存储元素list.add("I");list.add("love");list.add("you");list.add("❤");list.add("❤");//遍历集合Iterator it = list.iterator();while (it.hasNext()) {String s = (String) it.next();System.out.print(s + " ");}}
}//运行结果
I love you ❤ ❤

通过这段代码我们可以看到,List集合的特点——有序(存储和去取出的元素一直),可重复

我们再使用List存储学生对象并遍历看看

//Student 自行补充//StudentDemo类
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class StudentDemo {public static void main(String[] args) {List list = new ArrayList();Student s1 = new Student("张三", 20);Student s2 = new Student("李四", 30);Student s3 = new Student("王五", 40);list.add(s1);list.add(s2);list.add(s3);Iterator it = list.iterator();while (it.hasNext()) {Student s = (Student) it.next();System.out.println(s.getName() + "---" + s.getAge());}}
}//运行结果
张三---20
李四---30
王五---40//Student s = (Student)it.next();
//it.next()返回的是Object类型。
//(Student)it.next();是将Object类型强制转换成Student类型。
//这样才能够调用getName()方法和getAge()方法。

B:add() 使用方法:

package cn.bwh_02_List.ArrayList;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class StudentDemo {public static void main(String[] args) {List list = new ArrayList();Student s1 = new Student("张三", 20);Student s2 = new Student("李四", 30);Student s3 = new Student("王五", 40);list.add(s1);list.add(s2);list.add(s3);//迭代器遍历Iterator it = list.iterator();while (it.hasNext()) {Student s = (Student) it.next();System.out.println(s.getName() + "---" + s.getAge());}//利用List的功能遍历for (int x = 0; x < list.size(); x++){Student s = (Student) list.get(x);System.out.println(s.getName() + "---" + s.getAge());}}
}

上面几个实例中,我们使用了Iterator迭代器遍历,下面我们介绍一种特别的迭代器

C: 列表迭代器:

ListIterator listIterator():列表迭代器:List集合特有的迭代器

列表迭代器继承于Iterator迭代器,可以直接使用hasNext() 和next()方法

基本功能

//将指定的元素插入列表(可选操作)
void add(E e) //返回 true如果遍历正向列表,列表迭代器有多个元素
boolean hasNext() //返回列表中的下一个元素,并且前进光标位置
E next() //从列表中删除由 next()或 previous()返回的最后一个元素(可选操作)
void remove() //用 指定的元素替换由 next()或 previous()返回的最后一个元素(可选操作)
void set(E e)

特有功能

//获取上一个元素
Object previous()//判断是否有元素
boolean hasPrevious()

列表迭代器的好处是相比Iterator提供了更多的方法,并且可以实现正向遍历,才能逆向遍历,所以一般来说意义不大。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;public class Demo1 {public static void main(String[] args) {//创建集合对象List list = new ArrayList();//存储元素list.add("I");list.add("love");list.add("you");list.add("❤");list.add("❤");ListIterator lit= list.listIterator();//正向遍历while(lit.hasNext()){String s = (String)lit.next();System.out.print(s + " ");}System.out.println();//逆向遍历while (lit.hasPrevious()) {String s = (String) lit.previous();System.out.print(s + " ");}}
}//运行结果
I love you ❤ ❤
❤ ❤ you love I

(二) 并发修改异常问题

我创建了一个集合,并且遍历它,使用if语句判断 是否集合中存在"love"这个字符串,若存在,就增加一个"❤"元素,我们先顺着这个思路写一下代码:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;/**  并发修改异常*/
public class Demo2 {public static void main(String[] args) {//创建集合对象List list = new ArrayList();//存储元素list.add("I");list.add("love");list.add("you");Iterator it = list.iterator();while (it.hasNext()) {String s = (String) it.next();if ("love".equals(s)) {list.add("❤");}System.out.println(s);}}
}//运行结果(节选)
Exception in thread "main" java.util.ConcurrentModificationException

我们贴出JDK中对这个异常的解释:

This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.

当不允许这样的修改时,可以通过检测到对象的并发修改的方法来抛出此异常。

(1) 原因解释:

当我们对集合进行遍历的时候,我们会获取当前集合的迭代对象

//List为例,获取集合的迭代对象
Iterator it = list.iterator();

这个迭代对象中,封装了迭代器的方法与集合本身的一些方法,当我们在迭代中使用集合本身的add方法的时候,就产生了ConcurrentModificationException异常,通俗的说就是,在判断成功后,集合中元素增加了,但是迭代器不清楚,所以就报错,如果迭代器中含有这一种方法(假设),我们是用迭代器添加元素就不会有问题了。

针对这个问题,我们给出两个解决方案

(2) 解决方案:

方式1:迭代器迭代元素,迭代器修改元素

我们假想如果Iterator迭代器中有添加功能就好了,但很遗憾并没有,但是它的子接口ListIterator却拥有这个功能

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;public class Demo2 {public static void main(String[] args) {//创建集合对象List list = new ArrayList();//存储元素list.add("I");list.add("love");list.add("you");ListIterator lit = list.listIterator();while (lit.hasNext()) {String s = (String) lit.next();if ("love".equals(s)) {lit.add("❤");}System.out.print(s + " ");}}
}//运行结果
I love you

2:集合遍历元素,集合修改元素(普通for)

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;public class Demo2 {public static void main(String[] args) {//创建集合对象List list = new ArrayList();//存储元素list.add("I");list.add("love");list.add("you");for (int x = 0; x < list.size(); x++){String s = (String)list.get(x);if ("love".equals(s)){list.add("❤");}System.out.print(s + " ");}}
}//运行结果
I love you ❤

两者均可以解决并发修改异常的问题,但是通过运行结果也可以看出,方法一添加后,在本次遍历中不会输出添加的结果,而方法二却可以。

补充:增强for循环实现将集合进行遍历,也产生了并发修改异常,这是因为增强for在底层也是调用的集合本身的remove

(3) 总结:

在迭代器遍历时,如果需要对集合进行增删操作时,要调用迭代器本身的remove方法,或者选择使用普通for进行遍历

(三) Vector (过时,不推荐)

特有功能a:添加public void addElement(E obj)       --  add()b:获取public E elementAt(int index)       --  get()public Enumeration<E> elements()    --  iterator()

(四) List案例练习

下面的案例题目个别来源于网络,我们来整理,书写一下。

案例(一):集合嵌套存储和遍历元素的案例

需求:

我们班有学生,每一个学生是不是一个对象。所以我们可以使用一个集合表示我们班级的学生。ArrayList<Student>

但是呢,我们旁边是不是还有班级,每个班级是不是也是一个 ArrayList<Student>

而我现在有多个ArrayList<Student>。也要用集合存储,怎么办呢 ?

按照我们的想法就是这个样子的:ArrayList<ArrayList<Student>>

image


案例 (二): 获取10个1-20之间的随机数,要求不能重复

package cn.bwh_02_List.ArrayList.RandomDemo;import java.util.ArrayList;
import java.util.Random;
/**  分析:*      A:创建产生随机数的对象*      B:创建一个存储随机数的集合*      C:定义一个统计变量,从0开始*      D:判断统计遍历是否小于10*          小于10:*              若不存在:就添加,同时统计变量++*              若不存在:则不作处理*          大于10;*              不作处理*      E:遍历集合*/
public class ArrayDemo {public static void main(String[] args) {Random r = new Random();ArrayList<Integer> a = new ArrayList<Integer>();int count = 0;while (count < 10) {int number = r.nextInt(20) + 1;if (!a.contains(number)){a.add(number);count++;}}for (Integer i : a){System.out.print(i + " ");}}
}

案例 (三) 键盘录入多个数据

键盘录入多个数据,以0结束,要求在控制台输出这多个数据中的最值

package cn.bwh_02_List.ArrayList.InputMore;import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;/**  分析:*      A:创建键盘录入数据对象*      B:键盘录入多个数据,不知道数量,所以用集合存储*      C:以0结束——只要键盘录入的数据是0,就不继续录入数据了*      D:把集合转成数组*      E:对数组排序*      F:获取该数组中的最大索引的值*/
public class AeeayDemo {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入数据");ArrayList<Integer> a = new ArrayList<Integer>();while (true) {int number = sc.nextInt();if (number != 0) {a.add(number);} else {break;}}Integer[] i = new Integer[a.size()];a.toArray(i);Arrays.sort(i);System.out.println(i[i.length - 1]);}
}

案例 (五) 登录注册案例(使用集合)

image

package cn.bwh.pojo;/*** 这是用户基本描述类** @author BWH_Steven* @version v1.0*/public class User {private String username;private String password;public User() {}public User(String username, String password) {this.username = username;this.password = password;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}
package cn.bwh.dao;import cn.bwh.pojo.User;/*** 这是针对用户进行操作的接口** @author BWH_Steven* @version v1.0*/
public interface UserDao {/*** 这是用户登录功能** @param username 用户名* @param password 密码* @return 返回登录是否成功*/public abstract boolean isLogin(String username, String password);/*** 这是用户注册功能** @param user 要注册的用户信息*/public abstract void regist(User user);
}

因为注册的时候很可能还要填写
例如地址,性别,爱好等等信息(而登录功能的时候往往只需要用户名和密码),所以这个注册功能传进来的参数过多,因此用对象代替过多的参数,也就是说,通过传递对象(User user)包含众多信息避免了直接传递String username,password等等变量过多的问题

package cn.bwh.dao.impl;import cn.bwh.dao.UserDao;
import cn.bwh.pojo.User;import java.util.ArrayList;/*** 这是用户操作的具体实现类(集合类)** @author BWH_Steven* @version v1.0*/
public class UserDaoImpl implements UserDao {//为了多个集合能够使用同一个集合,就把集合定义为成员变量//为了不让外人看到,用privateprivate static ArrayList<User> array = new ArrayList<User>();@Overridepublic boolean isLogin(String username, String password) {//遍历集合,获取每一个用户,并且判断用户的用户名和密码是否和传递过来的匹配boolean flag = false;for (User u : array) {if (u.getUsername().equals(username) && u.getPassword().equals(password)) ;flag = true;break;}return flag;}@Overridepublic void regist(User user) {//把用户信息存入集合内array.add(user);}
}
package cn.bwh.test;import cn.bwh.dao.UserDao;
import cn.bwh.dao.impl.UserDaoImpl;
import cn.bwh.pojo.User;import java.util.Scanner;/*** 用户测试类** @author BWH_Steven* @version v1.0*/
public class UserTest {public static void main(String[] args) {//为了能够到主界面while (true) {System.out.println("------------初次见面,请多指教------------");System.out.println("1 登录");System.out.println("2 注册");System.out.println("3 退出");System.out.println("请输入你的选择");Scanner sc = new Scanner(System.in);//为了后面录入信息方便,所有的数据录入均使用字符串接受//Switch语句的多个地方要使用,对象就定义到外面String choicString = sc.nextLine();//调用注册功能,使用多态UserDao ud = new UserDaoImpl();switch (choicString) {case "1":System.out.println("----------------登录系统----------------");System.out.println("请输入用户名");String username = sc.nextLine();System.out.println("请输入密码");String password = sc.nextLine();//调用登录功能boolean flag = ud.isLogin(username, password);if (flag) {System.out.println("登陆成功");System.exit(0);//break; 这里break结束的是switch} else {System.out.println("用户名或者密码错误,登录失败");}break;case "2":System.out.println("--------------新用户注册---------------");System.out.println("请输入用户名");String newUsername = sc.nextLine();System.out.println("请输入密码");String newPassword = sc.nextLine();//把用户名和密码封装到一个类中User user = new User();user.setUsername(newUsername);user.setPassword(newPassword);ud.regist(user);System.out.println("注册成功");break;case "3":default:System.out.println("谢谢使用,感谢你曾经来过过");System.exit(0);break;}}}
}

小结:

dao层主要连接数据库,封装增删改查的数据库语句

daoimpl是实现dao层方法的接口,所以可以把具体实现的方法写在daoimpl中,dao层只写方法名就可以。

Pojo代表简单的Java对象

(五) List子类的特点(总结)

ArrayList:

​ 底层数据结构是数组查询快增删慢

线程不安全效率高

Vector:

​ 底层数据结构是数组查询快增删慢

线程安全效率低

LinkedList:

​ 底层数据结构是链表查询慢增删快

线程不安全效率高

使用具体情况

保证安全:Vector

​ (即使要安全,也不用这个,后面有替代的)

不保证安全:ArrayList或者LinkedList

查询多:ArrayList

增删多:LinkedList

结尾:

如果内容中有什么不足,或者错误的地方,欢迎大家给我留言提出意见, 蟹蟹大家 !_

如果能帮到你的话,那就来关注我吧!(系列文章均会在公众号第一时间更新)

在这里的我们素不相识,却都在为了自己的梦而努力 ❤

一个坚持推送原创Java技术的公众号:理想二旬不止

image

Java集合框架——List接口相关推荐

  1. java集合框架的接口_Java集合框架——Set接口

    第三阶段 JAVA常见对象的学习 集合框架--Set接口 List集合的特点是有序的,可重复的,是不是存在这一种无序,且能保证元素唯一的集合呢?(HashSet )这就涉及到我们今天所要讲的Set集合 ...

  2. Java集合框架之接口Collection源码分析

    本文我们主要学习Java集合框架的根接口Collection,通过本文我们可以进一步了解Collection的属性及提供的方法.在介绍Collection接口之前我们不得不先学习一下Iterable, ...

  3. java集合框架的接口_Java集合框架之Collection接口详解

    Java是一门面向对象的语言,那么我们写程序的时候最经常操作的便是对象了,为此,Java提供了一些专门用来处理对象的类库,这些类库的集合我们称之为集合框架.Java集合工具包位于Java.util包下 ...

  4. Java.集合 框架,接口,常用集合特点比对

    框架 接口 Iterable 可迭代接口 获取迭代器方法(Iterator<T> iterator();),使用该方法进行遍历. 迭代器实现Iterator接口. boolean hasN ...

  5. java 集合接口原理_图文剖析java集合框架—Set接口

    Map接口图补充待续 继上一节讲解了List接口的常用实现类以及源码的一些分析,这节将讲解集合中的Set接口. HashSet: 底层原理:哈希表结构存储.对集合的迭代次序不作任何保证; 允许元素nu ...

  6. java 集合框架、迭代器、比较器 学习笔记

    java集合框架总览 接口.实现类.算法的定义 常见的集合接口 Set和List的区别 常见的集合实现类 java.util包中定义的实现类 集合算法的概念 Collection Algorithms ...

  7. Java集合框架中Map接口的使用

    在我们常用的Java集合框架接口中,除了前面说过的Collection接口以及他的根接口List接口和Set接口的使用,Map接口也是一个经常使用的接口,和Collection接口不同,Map接口并不 ...

  8. Java集合框架系列教程三:Collection接口

    翻译自:The Collection Interface 一个集合表示一组对象.Collection接口被用来传递对象的集合,具有最强的通用性.例如,默认所有的集合实现都有一个构造器带有一个Colle ...

  9. Java集合框架总结(5)——Map接口的使用

    Java集合框架总结(5)--Map接口的使用 Map用于保存具有映射关系的数据(key-vlaue).Map的key不允许重复,即同一个Map对象的任何两个key通过equals方法比较总是返回fa ...

最新文章

  1. 09_Flink入门案例、word-count程序(java和scala版本)、添加依赖、Flink Streaming和Batch的区别 、在集群上执行程序等
  2. 12-1-顺序文件归并-文件-第12章-《数据结构》课本源码-严蔚敏吴伟民版
  3. 在python中使用grpc和protobuf
  4. 【4】测试用例设计-判定表法
  5. shell 创建文件_vba代替鼠标打开文件夹
  6. 微信公众平台可为市民鉴别万余药品真伪
  7. Java的历史及发展
  8. 手拉手教你实现一门编程语言 Enkel, 系列 15
  9. AdBlock插件离线安装
  10. web前端基础知识 - CSS语言和功能
  11. 网络设置里计算机为什么有两个字,一计算机网络操作题.doc
  12. 全渠道客户体验是什么?如何创建全渠道营销平台?
  13. 将.npy文件转化为灰度图像
  14. Java通过openOffice实现word,excel,ppt转成pdf实现在线预览
  15. yolov3运行及保存检测视频(包括摄像头)
  16. 2018“人工智能”:是彻底复苏?还是起落轮回?| 抢票
  17. CRC16校验的原理
  18. Mac OSX常用软件
  19. 深入理解JUC的8锁现象
  20. 聊聊四方支付通道那些事

热门文章

  1. 虾米音乐代码注释惊现“穷逼vip”程序员又背锅了
  2. 互联网服务器信息检索,网络信息检索的一般方法
  3. js实现局部刷新数据
  4. USB转串口数据线Vista驱动
  5. 远程桌面时,如何登录没有设置密码的系统
  6. 华为AirEngine 5762S-11面板AP配置
  7. 搭建无广告免费小说网站------简述(一)
  8. Docker fille实例讲解
  9. 棋盘格自动生成器——四种格式(格雷码棋盘格、圆点、二维码棋盘格)
  10. 青少年qsnctf [登录试试] 攻略