Bootstrap

Collection迭代器原理

//体现结构

//迭代器 iterator
interface Iterator<E>{
    boolean hasNext() ;判断是否有下一个可以迭代的元素
    E next() ;获取下一个元素
}

interface Iterable<T>{
     Iterator<E> iterator();
}

interface Collection<E> extends Iterable  {
         Iterator<E> iterator();
}

interface List<E> extends Collection<E>{
        Iterator<E> iterator();
}

//具体的子实现类
public class ArrayList<E> implements List<E>{

        public Iterator<E> iterator() {
                return new Itr();
        }

        //私有的成员内部类Itr
        private class Itr implements Iterator<E> {

                boolean hasNext(){

                }

                Object next(){
                ...
               }
        }
}

原理:就是ArrayList集合的内部类实现Itr间接实现了两个功能!
出现了异常"ConcurrentModificationException":并发修改异常

  什么叫并发:在某个时间点上同时进行!
  在集合这块出现ConcurrentModificationException原因:
  当使用迭代器去遍历元素的时候,同时不能使用集合对象去操作(修改或添加...)元素,就会出现这个异常!
  因为,迭代器在遍历元素的时候,集合添加一个新的元素,迭代器不知道!
  解决方案:

  Collection没有直接操作----->子接口List特有功能(ListIterator:列表迭代器/List集合普通for+size()+get(int index))
          1)集合遍历,集合添加
          2)迭代器遍历,迭代器遍历

增强For循环

Jdk5新特性:<泛型>,增强for,可变参数,静态导入(导入到方法级别:方法必须静态)...


 增强for:是在集合/数组中存储的引用类型中使用居多,代替集合迭代器的,简化书写代码
  格式:
          for(集合中存储的数据类型 变量名 : 集合对象){
              使用这个变量名即可;
          }

          注意:
                  要使用增强for遍历集合,集合对象不能null;
                  防止空指针异常,在使用增强for之前,对集合进行非空判断!
List集合特点:
      元素有序(存储和取出一致),而且元素可以重复!
 Set集合:
      元素唯一的,无序(存储和取出不一致)

List集合是Collection集合的子接口,它集合遍历方式:
      1)Collection的Object[] toArray()
      2)Collection的Iterator iterator() ;
      3)使用size()+ 存储的数据类型 get(int index)通过角标获取元素内容 :普通for循环格式
      4)ListIterator<E> listIterator()List集合的专有遍历方式 :列表迭代器
      5)增强for循环

List集合常用三个子实现类特点:

    实际需求:单线程中,使用List完成一些事情,没有明确规定具体使用哪个实现类;默认使用ArrayList集合!
    默认:ArrayList
            底层数据结构是数组-->查询快,增删慢! (数组,通过整数索引查询)
                           元素查找:  顺序查找,二分搜索(折半查找),哈希查找

                            43,50,66,70,---->哈希查询,哈希表的长度10
                                43 % 10 = 3
            线程角度:
                    线程不安全的类,是一个不同步,执行效率高!
                    底层扩容机制1.5倍
    Vector
            底层数据结构是数组-->查询快,增删慢!
             线程角度:
                    线程安全的类,是同步的,执行效率低! 多线程环境下使用居多,单线程使用ArrayList代替Vector
    LinkedList
            底层数据是链表, 查询慢,增删快
            线程角度:
                    线程不安全的类,不同步的,执行效率高!

项目:

使用集合模拟用户登录/注册操作,ArrayList集合存储用户名和密码

提示:

注册给集合中添加元素

登录,是遍历集合获取用户的信息

按照代码分层写:

com.qf.pojo---->User用户类 属性:字符串的username,password

com.qf.dao---->UserDao:针对用户操作的接口

注册:可以先不考虑重复

void register(User user) ;

boolean isLogin(String name,string pwd) ;

com.qf.dao.impl---->UserDaoImpl:用户操作的接口实现

完成上面功能实现

com.qf.test: UserTest完成测试

选择1,注册 ,2 登录 , 3退出

键盘录入对应的选择,然后完成功能调用!

项目名: Arraylist-Login-Register

  1. 用户实体类

/**
 * 用户实体类--描述用户的属性:用户名和密码
 */
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;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

2.针对用户操作数据访问接口实现层

import com.qf.dao.UserDao;
import com.qf.pojo.User;

import java.util.ArrayList;
import java.util.List;

/**
 *针对用户操作数据访问接口实现层
 *
 *
 */
public class UserDaoImpl implements UserDao {

    //静态实例
    private static List<User> list = new ArrayList<>() ;
    /**
     * 登录和注册的时候,需要使用同一个集合,这个集合被共用
     */
   /* static{
        List<User> list  = new ArrayList<>() ;
    }*/

    /**
     * 这个功能,用户登录功能
     * @param username  键盘录入 用户名
     * @param password  键盘录入的密码
     * @return  返回true,登录成功;否则,登录失败
     */
    @Override
    public boolean isLogin(String username, String password) {
        System.out.println(list); //测试
        //假设思想
        boolean flag = false ;//false:不成功
        //遍历List集合,取数据
        //增强for
        if(list!=null){ //防止空指针异常
            for(User u :list){
                //判断如果当前键盘录入的username和集合中的包含的用户的用户名一致,
                // 同时 键盘录入的密码和集合中包含的用户的密码一致,return true
                if(username.equals(u.getUsername()) && password.equals(u.getPassword())){
                    flag = true ;
                    break ;
                }
            }
        }

        return flag ;
    }

    /**
     * 这个功能是用户注册功能
     * @param user 需要注册的用户
     */
    @Override
    public void register(User user) {
        //创建一个List集合,存储用户
       // List<User> list = new ArrayList<>() ;

        list.add(user) ;
    }

  /*  @Override
    public List<User> findAll() {
        for(User user:list){
            System.out.println(user);
        }
        return list;
    }*/
}
  1. 针对用户操作的数据访问层

import com.qf.pojo.User;

import java.util.List;

/**
 * dao----数据访问对象--->以后这层代码直接操作"数据库"
 *
 * 针对用户操作的数据访问层
 */
public interface UserDao {

    /**
     * 这个功能,用户登录功能
     * @param username  键盘录入 用户名
     * @param password  键盘录入的密码
     * @return  返回true,登录成功;否则,登录失败
     */
    boolean isLogin(String username,String password) ;

    /**
     * 这个功能是用户注册功能
     * @param user 需要注册的用户
     */
    void register(User user) ;


    //List<User> findAll() ;//查询所有用户
}
  1. 测试类

package com.qf.test;

import com.qf.dao.UserDao;
import com.qf.dao.impl.UserDaoImpl;
import com.qf.pojo.User;

import java.util.Scanner;

/**
 * 测试类
 */
public class UserTest {
    public static void main(String[] args) {

        while(true){
            //给出一些选项
            System.out.println("-----------------------欢迎访问xxx用户管理系统--------------------------") ;
            System.out.println("1,登录 2,注册, 3,退出");

            //创建键盘录入对象
            Scanner sc = new Scanner(System.in) ;
            System.out.println("请输入您的选择器:") ;
            String choiceNum = sc.nextLine() ;

            //接口多态:
            UserDao ud = new UserDaoImpl() ; //使用注册和登录功能
            switch (choiceNum){
                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.out.println("进入后台管理系统") ;
                        System.exit(0) ;
                    }else{
                        System.out.println("对不起,用户名或者密码输入错误!");

                    }
                    break ;
                case "2" :
                    System.out.println("-----------------欢迎进入注册界面-------------------------");
                    //录入用户名和密码,调用用户的注册功能
                    System.out.println("请输入用户名:") ;
                    String name = sc.nextLine() ;

                    System.out.println("请输入密码:") ;
                    String pwd = sc.nextLine() ;

                    //封装用户数据
                    User user = new User() ;
                    user.setUsername(name) ;
                    user.setPassword(pwd) ;

                    //调用注册功能
                    ud.register(user) ;
                    System.out.println("恭喜您,注册成功!");
                    break ;
                case "3":
                default:
                    System.out.println("谢谢使用,欢迎下次再来,再见!");
                    //break ;
                    System.exit(0) ; //终止jvm了
            }
        }

    }
}

运行结果示例:

;