Calculator console app in Java Here is my source code for my very first app in Java. I am completely new to the language; any help and criticism is welcomed!
package com.company;

import java.util.*;

public class Main {

    public static float multiply(float a, float b)
    {
        return a*b;
    }

    public static float divide(float a, float b)
    {
        return a/b;
    }

    public static float addition(float a, float b)
    {
        return a+b;
    }

    public static float subtraction(float a, float b)
    {
        return a-b;
    }

    public static void main(String[] args)
    {
        Scanner scanner;
        float firstNum, secondNum, result;
        String operation;

        scanner = new Scanner(System.in);
        while(true){
            System.out.println(&quot;Select operation (*,/,+,-)&quot;);
            operation = scanner.next();
            if (operation.matches(&quot;[*/+-]&quot;)) {
                break;
            } else {
                System.out.println(&quot;Invalid operation&quot;);
            }
        }
        System.out.println(&quot;Type in first number&quot;);
        firstNum = scanner.nextFloat();

        System.out.println(&quot;Type in second number&quot;);
        secondNum = scanner.nextFloat();

        switch(operation)
        {
            case &quot;*&quot;: result = multiply(firstNum, secondNum); break;
            case &quot;/&quot;: result = divide(firstNum, secondNum); break;
            case &quot;+&quot;: result = addition(firstNum, secondNum); break;
            case &quot;-&quot;: result = subtraction(firstNum, secondNum); break;
            default: result = 0;
        }

        System.out.println(&quot;Result of your operation is &quot; + result);
    }
}
For a first application in Java, good job!
I have some suggestions for your code.
When using regex, try to uses the java.util.regex.Pattern class instead of the java.lang.String#matches method.
When using the java.lang.String#matches method, the regex pattern is recompiled each time the method is called. This can cause a slowdown in your method execution.
How to uses the matcher
Pattern pattern = Pattern.compile(&quot;[*/+-]&quot;);
while (true) {
   //[...]
   if (pattern.matcher(operation).matches()) {
      //[...]
   }
   //[...]
}

Extract some of the logic to methods.
Extracting code can make the code shorter and easier to read. Also when you have logic that does the same thing, you can generally move it into a method and reuse it.

You can make a method that asks a question and read the next float; this will allow you to reuse the same method.

public static void main(String[] args) {
   //[...]
   firstNum = askQuestionAndReceiveFloat(scanner, &quot;Type in first number&quot;);
   secondNum = askQuestionAndReceiveFloat(scanner, &quot;Type in second number&quot;);
   //[...]
}

private static float askQuestionAndReceiveFloat(Scanner scanner, String question) {
   System.out.println(question);
   return scanner.nextFloat();
}


You can extract the logic to parse the operation.

private static String askForOperation(Pattern pattern, Scanner scanner) {
   String operation;
   while (true) {
      System.out.println(&quot;Select operation (*,/,+,-)&quot;);
      operation = scanner.next();

      if (pattern.matcher(operation).matches()) {
         break;
      } else {
         System.out.println(&quot;Invalid operation&quot;);
      }
   }
   return operation;
}


If you are using Java 14, you can use the newer version of the switch-case and return the value.

private static float getResult(float firstNum, float secondNum, String operation) {
   return switch (operation) {
      case &quot;*&quot; -&gt; multiply(firstNum, secondNum);
      case &quot;/&quot; -&gt; divide(firstNum, secondNum);
      case &quot;+&quot; -&gt; addition(firstNum, secondNum);
      case &quot;-&quot; -&gt; subtraction(firstNum, secondNum);
      default -&gt; 0;
   };
}

Those's changes will make the main method shorter and easier to read!
Use java.io.PrintStream#printf instead of java.io.PrintStream#println when you have to concatenate
java.io.PrintStream#printf offer you to use patterns to build the string without concatenating it manually. The only downside is you will be forced to add the break line character yourself; in java you can use the %n to break the line (portable between various platforms) or uses the traditional \n / \r\n.
System.out.printf(&quot;Result of your operation is %s%n&quot;, result);

Refactored code
public static float multiply(float a, float b) {
   return a * b;
}

public static float divide(float a, float b) {
   return a / b;
}

public static float addition(float a, float b) {
   return a + b;
}

public static float subtraction(float a, float b) {
   return a - b;
}

private static float askQuestionAndReceiveFloat(Scanner scanner, String question) {
   System.out.println(question);
   return scanner.nextFloat();
}

private static String askForOperation(Pattern pattern, Scanner scanner) {
   String operation;
   while (true) {
      System.out.println(&quot;Select operation (*,/,+,-)&quot;);
      operation = scanner.next();

      if (pattern.matcher(operation).matches()) {
         break;
      } else {
         System.out.println(&quot;Invalid operation&quot;);
      }
   }
   return operation;
}

private static float getResult(float firstNum, float secondNum, String operation) {
   return switch (operation) {
      case &quot;*&quot; -&gt; multiply(firstNum, secondNum);
      case &quot;/&quot; -&gt; divide(firstNum, secondNum);
      case &quot;+&quot; -&gt; addition(firstNum, secondNum);
      case &quot;-&quot; -&gt; subtraction(firstNum, secondNum);
      default -&gt; 0;
   };
}

public static void main(String[] args) {
   Pattern pattern = Pattern.compile(&quot;[*/+-]&quot;);
   Scanner scanner = new Scanner(System.in);
   float firstNum, secondNum, result;
   String operation = askForOperation(pattern, scanner);

   firstNum = askQuestionAndReceiveFloat(scanner, &quot;Type in first number&quot;);
   secondNum = askQuestionAndReceiveFloat(scanner, &quot;Type in second number&quot;);
   result = getResult(firstNum, secondNum, operation);

   System.out.printf(&quot;Result of your operation is %s%n&quot;, result);
}

Also, I suggest to handle the x / 0 case :)