A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 WosLovesLife 于 2015-11-6 13:31 编辑

集合其实已经学完了,汇总的时候想着用集合来做一个注册登录之类的东西
于是就为下面的内容耗费了两天的空闲时间。




第一天基本写完了大多数代码,第二天就是加了一个猜数字的小游戏
因为想着不能登录完了之后啥都干不了嘛。
但是以为很简单的功能,却出现了很多没有料到的问题,还有现在也没能理解的问题。



在此过程中遇到了很多问题,即使现在也还还很不完善。不过这种解决问题的感觉很不错。
还有一个关于Scanner类的 nextInt();/nextLine();/next();方法的测试,因为字数超了,所以放在二楼


代码篇幅较长,但是请不要直接无视跳过,二楼和三楼还有内容。
我中间加了很多注释,以及问题和解决方法也都写在了里面。
每段代码我都会写上注释上是干嘛用的,


有兴趣的同学,可以把代码复制到eclipse自己运行一下看看。包名请自行修正,谢谢。




下面是一个javabean类。用于隔离开每个用户的信息。
  1. package LoginAndRegister151104;

  2. /**
  3. * 一个javabean类,只是提供两个成员变量和对应的构造、getter/setter。
  4. * @author WosLovesLife
  5. *
  6. */
  7. public class Users {
  8.         private String _userName;
  9.         
  10.         private String _passWord;

  11.         public Users() {
  12.                 super();
  13.                 // TODO 自动生成的构造函数存根
  14.         }

  15.         public Users(String _userName, String _passWord) {
  16.                 super();
  17.                 this._userName = _userName;
  18.                 this._passWord = _passWord;
  19.         }

  20.         public String get_userName() {
  21.                 return _userName;
  22.         }

  23.         public void set_userName(String _userName) {
  24.                 this._userName = _userName;
  25.         }

  26.         public String get_passWord() {
  27.                 return _passWord;
  28.         }

  29.         public void set_passWord(String _passWord) {
  30.                 this._passWord = _passWord;
  31.         }
  32.         
  33.         
  34. }
复制代码

下面是操作方法的接口,可以说并没有什么用。
  1. package LoginAndRegister151104;

  2. public interface IFunctions {
  3.         public abstract boolean login(String _userName,String _passWord);
  4.         
  5.         public abstract boolean register(String _userName,String _passWord);
  6. }
复制代码



下面是主要的操作方法,实现了上面的接口,包含了 注册 功能,和 登录 功能
  1. package LoginAndRegister151104;

  2. import java.util.ArrayList;
  3. import java.util.List;

  4. /**
  5. * 主要的操作实现类
  6. *
  7. * 由于还没有学习IO和数据库,所以由集合来实现数据存储和校验 以下方法用Map|HashMap实现,更方便
  8. * 但本案例用List|ArrayList方式来实现功能
  9. *
  10. * 该类用于操作Users数据的功能实现 继承自接口IFunctions
  11. *
  12. *
  13. * @author WosLovesLife
  14. * @version v1.0
  15. */
  16. public class Functions implements IFunctions {

  17.         /*
  18.          * 创建一个私有的集合,由于还没学习IO和数据库 所以临时用数组来存储和校验用户信息。
  19.          */
  20.         private static List<Users> user = new ArrayList<Users>();

  21.         // 实现接口方法,用于登录操作。
  22.         @Override
  23.         public boolean login(String _userName, String _passWord) {

  24.                 /*
  25.                  * 用foreach循环遍历Users集合,来校验形参(登录信息)是否存在 存在即成功,否则登录失败。
  26.                  * 之所以这里将账号和密码打包成一个Users对象 是为了将每个账号所对应的密码关联起来,不然可能存在安全问题。
  27.                  * 因为这里使用的是ArrayList而不是Map 所以账号和密码需要封装成两个集合。
  28.                  * 因为如何让user集合和password集合中的元素关联起来是一件较复杂的事情。
  29.                  * 所以直接打包成一个对象,校验时自然不会将这个账号“串”到另一个密码上
  30.                  */
  31.                 for (Users u : user) {
  32.                         if (u.get_userName().equals(_userName)
  33.                                         && u.get_passWord().equals(_passWord)) {
  34.                                 System.out.println("登录成功");
  35.                                 return true;
  36.                         }
  37.                 }
  38.                 System.out.println("账号或密码错误,请重新登陆");
  39.                 return false;
  40.         }

  41.         // 实现接口方法,用于注册操作。
  42.         @Override
  43.         public boolean register(String _userName, String _passWord) {
  44.                 if (_userName.length() < 4 || _passWord.length() < 4) {
  45.                         System.out.println("长度必须大于3位!");
  46.                         return false;
  47.                 } else {
  48.                         for (Users u : user) {
  49.                                 if (u.get_userName().equals(_userName)) {
  50.                                         System.out.println("账户已存在!");
  51.                                         return false;
  52.                                 }

  53.                         }
  54.                         /*
  55.                          * 如果以上情况都没发生
  56.                          * 就将传入的账号和密码,传入Users类中。
  57.                          * 生成一个新的Users对象,存进集合
  58.                          */
  59.                         Users us = new Users();
  60.                         us.set_userName(_userName);
  61.                         us.set_passWord(_passWord);
  62.                         user.add(us);
  63.                         System.out.println("注册成功~");
  64.                         return true;
  65.                 }
  66.         }/*
  67.          * public boolean register2(String userName, String ps) { boolean a = false;
  68.          * if(userName.length() >=4 && ps.length() >= 4) { for (Users u : user) { if
  69.          * (u.get_userName().equals(userName)) { System.out.println("账户已存在!"); a =
  70.          * true; break; } } if(!a){ Users us= new Users();
  71.          * us.set_userName(userName); us.set_passWord(ps); user.add(us); return
  72.          * true; } } return false; }
  73.          */
  74. }
复制代码


下面是测试类 main方法

  1. package LoginAndRegister151104;

  2. import java.util.Scanner;
  3. import games151105.GuessNumber;

  4. /**
  5. * 测试代码
  6. *
  7. * @author WosLovesLife
  8. *
  9. */
  10. public class Test {

  11.         public static void main(String[] args) {
  12.                 Functions fs = new Functions();
  13.                 Scanner sc = new Scanner(System.in);

  14.                 // 为while循环加一个标签,因为while和switch都用break跳出,所以如果在switch里使用break只是跳出switch。
  15.                 // 这种情况相当于跳出多层循环。所以用标签来跳出指定循环层。
  16.                 // 此处也可以在要结束的地方写 exit(0); 来强制结束程序。
  17.                 loop: while (true) {
  18.                         System.out.println("输入 1 登录\r输入 2 注册\r输入 其他字符 退出");

  19.                         String s1 = sc.nextLine();
  20.                         switch (s1) {
  21.                         case "1":
  22.                                 System.out.println("请输入账号:");
  23.                                 String username = sc.nextLine();
  24.                                 System.out.println("请输入密码:");
  25.                                 String password = sc.nextLine();

  26.                                 // 将录入的数据传进登录方法,返回是否登录成功。
  27.                                 boolean b = fs.login(username, password);
  28.                                 if (b == true) {

  29.                                         // 如果登录成功,就可以有运行游戏的权利。
  30.                                         System.out.println("猜数字游戏,是否开始? y/n");
  31.                                         String temp = sc.nextLine();
  32.                                         if (temp.equals("y") || temp.equals("Y")) {
  33.                                                 
  34.                                                 /*
  35.                                                  * !!!!!!!!!!!!!!!
  36.                                                  * !!!!!!!!!!!!!!!
  37.                                                  * 这里之所以要用返回值来判断是否循环是因为
  38.                                                  * 在游戏内类无法自己实现良好的循环,会有bug。
  39.                                                  * 暂时没有解决。
  40.                                                  */
  41.                                                 boolean s = GuessNumber.startGuess();
  42.                                                  while(s == true){
  43.                                                          s = GuessNumber.startGuess();
  44.                                                 }
  45.                                                 break;
  46.                                         } else {
  47.                                                 System.out.println("已退出登录");
  48.                                                 break;
  49.                                         }
  50.                                 }
  51.                                 break;
  52.                         case "2":
  53.                                 System.out.println("请输入账号:");
  54.                                 String username1 = sc.nextLine();
  55.                                 System.out.println("请输入密码:");
  56.                                 String password1 = sc.nextLine();
  57.                                 boolean a = fs.register(username1, password1);
  58.                                 break;
  59.                         default:
  60.                                 System.out.println("感谢使用");
  61.                                 break loop;
  62.                         }
  63.                 }
  64.         }
  65. }
复制代码





8 个回复

正序浏览
sshh11 发表于 2015-11-7 22:46
大神  写的有点多啊。。

其实有很多都是注释……遇到了一些问题,一般来说应该回避用更合适的方式做,不过因为有意思,有点往里钻牛角尖了,所以写的东西也多一些。
回复 使用道具 举报
雨来 发表于 2015-11-7 21:38
你保存成一个java文件  放一个链接上去   因为  不字数限制感觉发的不连贯怎么看 ...

很好的建议,因为每个代码端都是单独的一个类,所以我就没有在意这样的问题。
回复 使用道具 举报
sshh11 中级黑马 2015-11-7 22:46:36
7#
大神  写的有点多啊。。
回复 使用道具 举报
你保存成一个java文件  放一个链接上去   因为  不字数限制感觉发的不连贯怎么看
回复 使用道具 举报
                                                  ……就这么沉了……
回复 使用道具 举报
果然这种长篇大论没人爱看啊………………
回复 使用道具 举报
继续上面


下面是一个单独的用来测试上面提到的Scanner类的方法nextInt();nextLine();next();特性的类。
  1. package test20151105;

  2. import java.util.Scanner;

  3. /**
  4. * 额外的单独测试方法
  5. * 用来测试在nextInt()下面使用nextLine()
  6. *
  7. * @author WosLovesLife
  8. *
  9. */
  10. public class Next {
  11.         public static void main(String[] args) {
  12.                 while (true) {
  13.                         Scanner sc = new Scanner(System.in);
  14.                         System.out.println("下面输出a");
  15.                         int a = sc.nextInt();
  16.                         System.out.println(a);
  17.                         
  18.                         System.out.println("下面输出b");
  19.                         String b = sc.nextLine();
  20.                         System.out.println(b);
  21.                         
  22.                         System.out.println("下面输出c");
  23.                         String c = sc.nextLine();
  24.                         System.out.println(b);
  25.                         
  26.                         System.out.println("下面输出c");
  27.                         String d = sc.nextLine();
  28.                         System.out.println(b);
  29.                 }
  30.         }
  31. }
复制代码



回复 使用道具 举报
本帖最后由 WosLovesLife 于 2015-11-7 15:50 编辑

继续上面


下面是猜数字小游戏
  1. package games151105;

  2. import java.util.Scanner;

  3. /**
  4. * 一个猜数字小游戏 此方法有一个关键性的“小问题”
  5. *
  6. * @author WosLovesLife
  7. *
  8. */
  9. public class GuessNumber {

  10.         public static boolean startGuess() {
  11.                 // 用于计数
  12.                 int _count = 0;

  13.                 Scanner sc = new Scanner(System.in);

  14.                 int _goal = (int) (Math.random() * 100 + 1);

  15.                 System.out.println("现在有一个大于0小于等于100的数字\r试试你多少次能猜对呢。");
  16.                 while (true) {

  17.                         // 每猜一次,记一个数
  18.                         _count++;

  19.                         int _guessResult = sc.nextInt();

  20.                         if (_goal == _guessResult) {
  21.                                 if (_count > 15) {
  22.                                         System.out.println("少年郎,要多扶老奶奶过马路啊,居然猜了" + _count
  23.                                                         + "次,要再试一次吗? y/n");
  24.                                 } else if (_count > 10) {
  25.                                         System.out.println("继续加油啊,猜了" + _count
  26.                                                         + "次才猜对~再来一次吧? y/n\r");
  27.                                 } else if (_count > 5) {
  28.                                         System.out.println("还不错哦,猜了" + _count
  29.                                                         + "次就猜对了~是否在玩一次? y/n\r");
  30.                                 } else {
  31.                                         System.out.println("真厉害!只猜了" + _count
  32.                                                         + "次就猜对了~是否在玩一次? y/n\r");
  33.                                 }

  34.                                 /*
  35.                                  * 重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点
  36.                                  * 重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点
  37.                                  * 重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点
  38.                                  * 重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点重点 为了唤起注意了只好这样做了…………~
  39.                                  *
  40.                                  * 注意看,下面String t = sc.next(); 而不是nextLine(); scanner有个扫描器
  41.                                  * nextLine方法是返回当前行的其余部分,当前位置移至下一行的行首。
  42.                                  *
  43.                                  * 可以理为,由于我上面创建的Scanner对象sc
  44.                                  * 已经调过一个nextInt();方法,这个方法会忽略回车,所以就会留下一个回车没有被回收。
  45.                                  * 在下面这里如果我使用nextLine(),而这个方法会处理回车,所以一上来,你还没有输入东西
  46.                                  * 它就已经回车了,也就是输入完成了。
  47.                                  *
  48.                                  * 所以,如果Debug的时候就会看到 如果上面int i = sc.nextInt(); 下面再写一个 String s =
  49.                                  * sc.nextLine(); 它不等你输入s的值,就已经给String赋了一个 "" 的值
  50.                                  *
  51.                                  * 处理这种问题 要么写两个nextLIne();使用第二个(因为第一个不起作用嘛) 要么写一个 next();
  52.                                  * next();方法会在扫面屏幕之前先处理回车。
  53.                                  *
  54.                                  * 这个问题昨天困扰了我很久啊啊啊
  55.                                  */
  56.                                 String t = sc.next();
  57.                                 if (t.equals("y") || t.equals("Y")) {
  58.                                                 return true;
  59.                                 } else {

  60.                                         //System.out.println("guess已退出登录");
  61.                                        
  62.                                         /*
  63.                                          * !!!!!!!!!!!!!!!
  64.                                          * !!!!!!!!!!!!!!!
  65.                                          * 当返回类型是void时,直接写一个return代表结束方法,其实每一个方法最后都隐含一个return。
  66.                                          * 当返回类型是void时,直接写一个return代表结束方法,其实每一个方法最后都隐含一个return。
  67.                                          * 但是如果运行了两次此方法之后再退出,就会继续循环while。
  68.                                          * 但是如果运行了两次此方法之后再退出,就会继续循环while。
  69.                                          */
  70.                                         return false;
  71.                                        
  72.                                 }
  73.                                 // return sc.next();
  74.                         }
  75.                         if (_goal < _guessResult) {
  76.                                 System.out.println("大了");
  77.                                 continue;
  78.                         }
  79.                         if (_goal > _guessResult) {
  80.                                 System.out.println("小了");
  81.                                 continue;
  82.                         }
  83.                 }
  84.         }
  85. }
复制代码



回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马