简体   繁体   中英

how to fix my conditions for the while loop in java

my code is simple; check a string for how much there are numbers, lowercase lettters, uppercase letters and special characters but it has to have at least one of each;

i think there is a problem with the AND or the OR of the conditions in my while loop

public static void main(String[] args) {
        Scanner scn = new Scanner(System.in);
        String name = scn.nextLine();
        checkPass(name);
}

public  static void checkPass (String str){
    int toul = str.length();
    int normalLower=0;
    int normalUpper=0;
    int number=0;
    int special=0;
    while(normalLower==0 || normalUpper==0 || number==0 || special==0) {
        for (int i = 0; i < toul; i++) {
            String s = String.valueOf(str.charAt(i));
            if (s.matches("^[a-z]*$")) {
                normalLower++;
            } else if (s.matches("^[A-Z]*$")) {
                normalUpper++;
            } else if (s.matches("^[0-9]*$")) {
                number++;
            } else {
                special++;
            }
        }
    }
    System.out.println("normalupper " + normalUpper);
    System.out.println("normallower " + normalLower );
    System.out.println("number" + number);
    System.out.println("special " + special);
}

i expect it to ask for a string whenever a char type is missing but it simple doesn't

Try returning the boolean status from the checkPass method and put a while loop in your main method, the status will be the condition you are checking.

This way you can break the while loop if the entered string is passing your validation else the loop will continue asking for the valid input String :

public static void main(String[] args) throws Exception {
        Scanner scn = new Scanner(System.in);
        String name = scn.nextLine();
        while(checkPass(name)){
            name = scn.nextLine();
        }
    }

 // If the boolean retuned from this method is false it will break the while loop in main
 public static boolean checkPass(String str) {
     int toul = str.length();
     int normalLower = 0;
     int normalUpper = 0;
     int number = 0;
     int special = 0;
     for (int i = 0; i < toul; i++) {
         String s = String.valueOf(str.charAt(i));
         if (s.matches("^[a-z]*$")) {
             normalLower++;
         } else if (s.matches("^[A-Z]*$")) {
             normalUpper++;
         } else if (s.matches("^[0-9]*$")) {
             number++;
         } else {
             special++;
         }
      }
      System.out.println("normalupper " + normalUpper);
      System.out.println("normallower " + normalLower);
      System.out.println("number" + number);
      System.out.println("special " + special);
      return normalLower == 0 || normalUpper == 0 || number == 0 || special == 0;
 }

As an update to @Fullstack Guy answer, I would suggest using Character class for checking what type of character are we dealing with:

public static boolean checkPass(String str) {
    int normalLower=0;
    int normalUpper=0;
    int number=0;
    int special=0;
    for (char c : str.toCharArray()) {
        if (Character.isDigit(c)) {
            number++;
        } else if (Character.isUpperCase(c)) {
            normalUpper++;
        } else if (Character.isLowerCase(c)) {
            normalLower++;
        } else {
            special++;
        }
    }
    System.out.println("normalupper " + normalUpper);
    System.out.println("normallower " + normalLower);
    System.out.println("number" + number);
    System.out.println("special " + special);
    return normalLower == 0 || normalUpper == 0 || number == 0 || special == 0;
}

Here is a version using Java 8 Streams and lambda functions to get the counts:

public static String getType(int code){
    if(Character.isDigit(code)) return "number";
    if(Character.isLowerCase(code)) return "normalLower";
    if(Character.isUpperCase(code)) return "normalupper";
    return "special";
}

public static void checkPass(String s){
    Map map =s.chars().mapToObj(x->getType(x))
            .collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
    System.out.println(map);
}

Sample Run:

checkPass("PassWord"); Output ==> {normalupper=2, normalLower=6}

checkPass("P@ss@Wo1r d3"); Output ==> {special=3, number=2, normalupper=2, normalLower=5}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM