使用 Streams 模拟嵌套 for 循环过滤
我正在研究一个与Pokemon一起工作的项目。
我有一个PokemonRecord
记录,该记录具有2个参数,可用于2 PokemonTypes
。 PokemonRecord
的任何实例都可以具有1或2种类型。如果PokemonRecord
只有1个类型,则type2 == null
。以下方法的目的是采用pokemontypes
的数组,并生成所有可能的pokemonRecord
键入组合的列表,该组合可以抗拒所有这些给定类型。将“抵抗类型”视为一种单独的方法,该方法测试条件并返回boolean
。
这是预期输出的一个示例:
Enter the name of a Pokemon type: water
Enter the name of a Pokemon type: ground
Enter the name of a Pokemon type: grass
Enter the name of a Pokemon type: done
The following type combinations resist all of [water, ground, grass]:
Grass
Normal & Grass
Grass & Ice
Grass & Fighting
Grass & Flying
Grass & Psychic
Grass & Bug
Grass & Ghost
Grass & Dragon
Grass & Dark
Grass & Fairy
Flying & Dragon
Bug & Dragon
目前,我的代码按预期运行;但是,回顾过去,我想以不同的方式写一些东西 - 在国际象棋中,当您找到一个好的举动时,找到一个更好的动作。我最初使用了一种程序式式方法,以通过pokemontypes
的完整列表过滤并测试它们的每一个组合:
public static List<PokemonRecord> genMonResToAll(PokemonTypes... types) {
List<PokemonTypes> allTypes = //List of possible PokemonTypes that this Pokemon can have (PokemonTypes that are not weak to any inputted PokemonTypes)
List<PokemonRecord> outputList = new ArrayList<>();
//Add any single-type Pokemon that resists all types
for(PokemonTypes type : allTypes)
if(new PokemonRecord(type).isResistantToAll(types))
outputList.add(new PokemonRecord(type));
//Add any multi-type Pokemon that resists all types
for (int i = 0; i < allTypes.size() - 1; i++)
for (int j = i + 1; j < allTypes.size(); j++) {
PokemonRecord testMon = new PokemonRecord(allTypes.get(i), allTypes.get(j));
if (testMon.isResistantToAll(types))
otuputList.add(testMon);
}
return outputList;
}
//The functionality of any specific `Pokemon` or `PokemonTypes` method used isn't relevant, they all work as intended.
我现在试图使用<<<<<<代码>流 API。我能够确定如何将第一个循环转换为添加单型PokemonRecord
的循环,以基于流的声明语句。我在第二次缠住我的头时要困难得多。我当前带有第一个循环重构的代码是:
public static List<PokemonRecord> genMonResToAll(PokemonTypes... types) {
List<PokemonTypes> allTypes = //List of possible PokemonTypes that this Pokemon can have (PokemonTypes that are not weak to any inputted PokemonTypes)
//Add any single-type Pokemon that resists all types
List<PokemonRecord> outputList= allTypes.stream()
.map(PokemonRecord::new)
.filter(x -> x.isResistantToAll(types))
.collect(Collectors.toList());
//Add any multi-type Pokemon that resists all types
for (int i = 0; i < allTypes.size() - 1; i++)
for (int j = i + 1; j < allTypes.size(); j++) {
PokemonRecord testMon = new PokemonRecord(allTypes.get(i), allTypes.get(j));
if (testMon.isResistantToAll(types))
otuputList.add(testMon);
}
return outputList;
}
//The functionality of any specific `Pokemon` or `PokemonTypes` method used isn't relevant, they all work as intended.
I'm working on a project to do with Pokemon.
I have a PokemonRecord
record which has 2 parameters for 2 PokemonTypes
. Any instance of PokemonRecord
can have either 1 or 2 types. If the PokemonRecord
has only 1 type, then type2 == null
. The following method's purpose is to take an array of PokemonTypes
and generate a list of all possible PokemonRecord
type combinations that will resist all of those given types. Think of "resisting a type" as a separate method which tests a condition and returns a boolean
.
This is a sample of the expected output:
Enter the name of a Pokemon type: water
Enter the name of a Pokemon type: ground
Enter the name of a Pokemon type: grass
Enter the name of a Pokemon type: done
The following type combinations resist all of [water, ground, grass]:
Grass
Normal & Grass
Grass & Ice
Grass & Fighting
Grass & Flying
Grass & Psychic
Grass & Bug
Grass & Ghost
Grass & Dragon
Grass & Dark
Grass & Fairy
Flying & Dragon
Bug & Dragon
Currently, my code works as intended; however, looking back, I'd like to write some things differently - in chess, when you find a good move, find a better one. I initially used a procedural for-loop approach in order to filter through the full list of PokemonTypes
and test every single combination of them:
public static List<PokemonRecord> genMonResToAll(PokemonTypes... types) {
List<PokemonTypes> allTypes = //List of possible PokemonTypes that this Pokemon can have (PokemonTypes that are not weak to any inputted PokemonTypes)
List<PokemonRecord> outputList = new ArrayList<>();
//Add any single-type Pokemon that resists all types
for(PokemonTypes type : allTypes)
if(new PokemonRecord(type).isResistantToAll(types))
outputList.add(new PokemonRecord(type));
//Add any multi-type Pokemon that resists all types
for (int i = 0; i < allTypes.size() - 1; i++)
for (int j = i + 1; j < allTypes.size(); j++) {
PokemonRecord testMon = new PokemonRecord(allTypes.get(i), allTypes.get(j));
if (testMon.isResistantToAll(types))
otuputList.add(testMon);
}
return outputList;
}
//The functionality of any specific `Pokemon` or `PokemonTypes` method used isn't relevant, they all work as intended.
I'm now trying to rewrite this code to be more declarative using the Stream
API. I was able to work out how to convert the first loop, the loop that adds single-type PokemonRecord
, to a Stream-based declarative statement. I'm having a much harder time wrapping my head around the second. My current code with the first loop refactored is:
public static List<PokemonRecord> genMonResToAll(PokemonTypes... types) {
List<PokemonTypes> allTypes = //List of possible PokemonTypes that this Pokemon can have (PokemonTypes that are not weak to any inputted PokemonTypes)
//Add any single-type Pokemon that resists all types
List<PokemonRecord> outputList= allTypes.stream()
.map(PokemonRecord::new)
.filter(x -> x.isResistantToAll(types))
.collect(Collectors.toList());
//Add any multi-type Pokemon that resists all types
for (int i = 0; i < allTypes.size() - 1; i++)
for (int j = i + 1; j < allTypes.size(); j++) {
PokemonRecord testMon = new PokemonRecord(allTypes.get(i), allTypes.get(j));
if (testMon.isResistantToAll(types))
otuputList.add(testMon);
}
return outputList;
}
//The functionality of any specific `Pokemon` or `PokemonTypes` method used isn't relevant, they all work as intended.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于PokemonRecord是二维的,因此我认为您不应该使用流。这是一种没有流的更好方法:
null
添加到Alltypes和楼梯上迭代它(以获取所有可能的组合而无需重复):Since PokemonRecord's are twodimensional, I don't think you should use streams. This is a better approach without streams:
null
to allTypes and staircase iterate over it (to get all possible combinations without duplicates):