The Insanity Beyond Null
4. 演習
リスト内包表記の操作をリファクタリングします。
演習1
演習1 Java 11
fixMe
メソッドをリファクタリングして、null
との比較を行うfilter
を取り除いてください。
...
public final class Main {
public static final class Node {
...
public List<Node> getChildNodes() {
...
}
...
}
private static List<Node> getNodes() {
...
}
private static void fixMe() {
var list = getNodes().stream()
.map(n -> n.getChildNodes().stream().findFirst().orElse(null))
// 次の行は .filter(Objects::nonNull) でも同じ
.filter(n -> n != null)
.collect(Collectors.toList());
...
}
...
演習1 C# 8
FixMe
メソッドをリファクタリングして、null
との比較を行うWhere
を取り除いてください。
...
public sealed class Program
{
public sealed class Node
{
...
public IEnumerable<Node> ChildNodes { get; }
...
}
private static IEnumerable<Node> Nodes { get; } = ...;
private static void FixMe()
{
var list = Nodes
// ChildNodes が空のときは null に変換して処分を先送り
.Select(n => n.ChildNodes.FirstOrDefault())
.Where(n => n is {});
...
演習1 Swift 5
fixMe
関数をリファクタリングして、nil
との比較を行うfilter
を取り除いてください。
public class Node : CustomStringConvertible {
...
public let childNodes: [Node]
...
public var description: String { ... }
}
let nodes = [ ... ]
func fixMe() {
let list = nodes.map { $0.childNodes.first }
.filter { $0 != nil }
...
}
演習1 Kotlin 1.3
fixMe
関数をリファクタリングして、filterNotNull
を取り除いてください。
public class Node ... {
...
public val childNodes = ...
...
public override fun toString(): String {
...
}
}
val nodes = arrayOf(...)
fun fixMe() {
val list = nodes.map { it.childNodes.firstOrNull() }
.filterNotNull()
...
}
演習1 解答例
演習2
演習2 Java 11
fixMe
メソッドをリファクタリングして、null
との比較を行うfilter
を取り除いてください。
...
import static java.util.Map.entry;
public final class Main {
private static final Map<String, Runnable> COMMAND_MAP = Map.ofEntries(
entry("help", () -> printHelp()),
entry("quit", () -> exitProgram()),
entry("shutdown", () -> shutdownSystem()));
...
private static List<String> getCommandList() {
return List.of("help", "reboot", "shutdown");
}
private static void fixMe() {
var list = getCommandList().stream()
// Map#get(Object) の戻り値が null のときは処分を先送り
.map(COMMAND_MAP::get)
// 次の行は .filter(Objects::nonNull) でも同じ
.filter(r -> r != null)
.collect(Collectors.toList());
...
}
...
演習2 C# 8
FixMe
メソッドをリファクタリングして、null
との比較を行うWhere
を取り除いてください。
public static class Program
{
private static readonly ImmutableDictionary<string, Action> CommandMap
= new Dictionary<string, Action>()
{
["help"] = () => PrintHelp(),
["quit"] = () => ExitProgram(),
["shutdown"] = () => ShutdownSystem(),
}.ToImmutableDictionary();
...
private static IEnumerable<string> CommandList { get; }
= new[] { "help", "reboot", "shutdown" };
private static void FixMe()
{
var list = CommandList
// TryGetValue(TKey, out TVaue) の戻り値が false のときは
// null に変換
.Select(n => CommandMap.TryGetValue(n, out var action)
? action
: null)
.Where(a => a is {});
...
}
...
演習2 Swift 5
fixMe
関数をリファクタリングして、nil
との比較を行うfilter
を取り除いてください。
...
let commandMap = [
"help": { printHelp() },
"quit": { exitProgram() },
"shutdown": { shutdownSystem() }]
func getCommandList() -> [String] {
return ["help", "reboot", "shutdown"]
}
func fixMe() {
let list = getCommandList().map { commandMap[$0] }
.filter { $0 != nil }
...
}
演習2 Kotlin 1.3
fixMe
関数をリファクタリングして、filterNotNull
を取り除いてください。
val commandMap = mapOf(
"help" to { printHelp() },
"quit" to { exitProgram() },
"shutdown" to { shutdownSystem() })
...
fun getCommandList(): List<String> {
return listOf("help", "reboot", "shutdown")
}
fun fixMe() {
val list = getCommandList()
.map { commandMap.get(it) }
.filterNotNull()
...
}