One popular use case for pattern matching with switch is when working with different types of data in a program. Consider the following example of a WeatherStation class that has different types of sensors and returns the current temperature:
`public class WeatherStation {
private Sensor sensor;
public double getCurrentTemperature() {
return switch (sensor) {
case TemperatureSensor t -> t.reading();
case HumiditySensor h -> h.reading() * 0.9; // apply a 10% moisture correction
default -> 0.0; // in case of an unhandled sensor type, return 0
};
}
}
`
Here, we can see that a Sensor interface is used for the selector expression, and the case labels use patterns based on specific Sensor implementations: TemperatureSensor and HumiditySensor. This allows for a more concise and readable way of handling different types of data in the switch statement.
Another use case for pattern matching with switch is when dealing with enums. Before pattern matching was introduced, enums could only be used as constants in case labels, restricting the values that could be tested against in a switch statement. With the new feature, enums can now be qualified in case labels, allowing for more precise and flexible matching.
public enum Direction {
NORTH,
EAST,
SOUTH,
WEST
}
public void move(Direction direction) {
switch (direction) {
case NORTH,NORTH_WEST,NORTH_EAST -> moveUp();
case EAST,EAST_NORTH,EAST_SOUTH -> moveRight();
case SOUTH,SOUTH_EAST,SOUTH_WEST -> moveDown();
case WEST,WEST_NORTH,WEST_SOUTH -> moveLeft();
}
}
Here, the move() method uses a switch statement to easily handle moving in different directions based on the specified Direction enum value. With pattern matching, we can also specify directional combinations, such as NORTH_WEST and EAST_SOUTH, making our code more robust and flexible.
Finally, let's look at an example of how pattern matching can help with error handling in a switch statement. In the traditional switch, if the selector expression doesn't match any of the case labels, a default case can be used to handle the error. However, this can be tedious when dealing with multiple case labels and can lead to code duplication. In pattern matching, an exception is thrown if none of the case label patterns match the selector expression, making error handling more uniform and less error-prone.
public String getPlanetaryObject(PlanetaryBody body) {
return switch (body) {
case Planet p && p.getMass() > 1e29 -> p.getName() + " is a gas giant";
case Planet p && p.getMass() > 1e23 -> p.getName() + " is a rocky planet";
case Star s && s.getLuminosity() > 1e32 -> s.getName() + " is a bright star";
case Star s && s.getLuminosity() < 1e28 -> s.getName() + " is a dim star";
default -> throw new MatchException("Unable to determine type of planetary object: " + body.getName());
};
}
In this example, the getPlanetaryObject() method takes in a PlanetaryBody object, which can be either a planet or a star. The patterns used in the case labels consider additional conditions, such as the mass of the planet or the luminosity of the star. If none of the patterns match, a MatchException is thrown, making error handling more consistent and preventing any potential errors.
Conclusion
Pattern matching for switch is one of the most significant features introduced in Java in recent times. It allows for more flexible and concise control-flow structures.
Upgrade your Java skills by taking the Java SE 21 Professional Certified Developer certification.
Top comments (0)