我正在实现我的DIY
IoT
。我有一个中央节点(服务器),它接收来自不同来源的命令并执行它们。
输入格式:
<DEVICE_NAME>_<COMMAND> <DEVICE_NAME>_<COMMAND> <DEVICE_NAME>_<COMMAND>
<DEVICE_NAME>_<COMMAND> <DEVICE_NAME>_<COMMAND>
<DEVICE_NAME>_<COMMAND> <DEVICE_NAME>_<COMMAND> <DEVICE_NAME>_<COMMAND>
每一行可能包含多个命令。
我已经实现了一个命令执行服务器,它将 session 中的命令作为 InputStream
。然后我拆分数据并处理它:
private Device c0 = // Device constructor
private Device c1 = // Device constructor
private Device c2 = // Device constructor
private Device c3 = // Device constructor
private ExecutorService executor = Executors.newFixedThreadPool(3);
public void onConnection(InputStream in)
InputStreamReader isr = new InputStreamReader(in);
LineNumberReader reader = new LineNumberReader(isr);
String line = null;
while ((line = reader.readLine()) != null) {
String[] strings = line.split(",");
for (String raw : strings) {
String command = raw.substring(0, 3);
if (raw.startsWith("C0_")) {
executor.submit(() -> c0.execute(command));
} else if (raw.startsWith("C1_")) {
executor.submit(() -> c1.execute(command));
} else if (raw.startsWith("C2_")) {
executor.submit(() -> c2.execute(command));
} else if (raw.startsWith("C3_")) {
executor.submit(() -> c3.execute(command));
}
}
}
}
我知道代码看起来很丑。你有什么改进的想法吗?也许我可以使用 Steam API
?
感谢任何提示/建议。
更新
我试图通过只提交一次任务来清理代码,但编译器说 device
必须是 final
或 effectively final
所以这是行不通的:
String command = raw.substring(0, 3);
Device device;
if (raw.startsWith("C0_")) {
device = c0;
} else if (raw.startsWith("C1_")) {
device = c1;
} else if (raw.startsWith("C2_")) {
device = c2;
} else if (raw.startsWith("C3_")) {
device = c3;
}
executor.submit(() -> device.execute(command));
最佳答案
你可以像这样映射你的命令:
InputStreamReader isr = new InputStreamReader(is);
BufferedReader buffReader = new BufferedReader(isr);
Map<String, List<String>> map = buffReader.lines()
.map(s -> s.split(" "))
.flatMap(Arrays::stream)
.map(s -> s.split("(?<=_)", 2))
.collect(groupingBy(p -> p[0], mapping(p -> p[1], toList())));
更新
实际上你可以结合映射和提交:
// Register your devices
Map<String, Device> devices = new HashMap<>();
devices.put("c0", c0);
devices.put("c1", c1);
devices.put("c2", c2);
devices.put("c3", c3);
...
public void onConnection(InputStream in) {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader buffReader = new BufferedReader(isr);
buffReader.lines()
.parallel()
.map(s -> s.split(" "))
.flatMap(Arrays::stream)
.map(s -> s.split("(?<=_)", 2))
.forEach(p -> executor.submit(
() -> devices.get(p[0]).execute(p[1])
));
}
关于java - 将字符串从 InputStream 映射到 ExecutorService,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53269762/