我怎样才能用流解决以下练习
How can I solve the following exercise with streams
在下面的练习中,我应该保留所有房间,其中有 SmartLamps。我怎样才能用流解决这个问题?由于每个 SmartLamp 都有 Room 属性,我需要在房间和灯上进行流式传输。我试着用 anyMatch 来做,但找不到可行的解决方案。有人可以帮忙吗? (我知道不用流怎么解决)
public class SmartHome {
private final List<Room> rooms;
private final List<SmartLamp> lamps;
public void deleteRooms() {
rooms.stream().anyMatch(lamps.stream().map(SmartLamp::getRoom));
}
}
代码报错:
“类型不匹配:无法从 Stream 转换为 Predicate super Room>”
lamps.stream().map(SmartLamp::getRoom).anyMatch(rooms::contains);
谓词不需要流,您需要创建一个 lambda room -> ...
。
但是您已经必须为映射灯创建一个流,所以我将从该流开始。确实contains
不是很好,但也够精致了。
一个Set<Room>
会更好
我相信任何匹配都不是您想要的。任何匹配都是一种流方法,如果流中的任何内容与您想要的匹配,则 returns true 或 false。
但是不管你想要一个 Predicate
其形式为
List<Room> lampRoomList = lamps.stream().map(SmartLamp::getRoom).ToList()
//predicate is in the filter method
List<Room> roomsWithLamps = rooms.stream().filter(room.toroom -> lampRoomList.Contains(Room)).toList();
第二行中的 room 表示流中的对象。在你的情况下是一个房间。
第一行是保存 lamps 中所有房间的列表,因此您不需要为每个房间映射。
您可以在此处阅读有关谓词的更多信息
https://www.geeksforgeeks.org/java-8-predicate-with-examples/
I should keep all the Rooms, which have SmartLamps in it.
好的,所以你可以这样做...
public class SmartHome {
private final List<Room> rooms;
private final List<SmartLamp> lamps;
void deleteRoomsWithoutSmartLamps() {
var goodRooms = roomsWithSmartLamps();
// This line will remove the bad rooms from the list
rooms = rooms.stream().filter( r -> goodRooms.contains(r)).collect(toList())
}
// This method gives you a list of rooms with smart lamps
public List<Room> roomsWithSmartLamps() {
var goodRooms = lamps.stream().filter( lamp -> lamp.isSmartLamp() ).map(lamp -> lamp.getRoom()).filter(room != null)collect(toList());
return goodRooms;
}
}
这是否解决了您的问题?评论告诉我吧。
你可以试试
lamps.stream()
.map(SmartLamp::getRoom)
.filter(rooms::contains)
.collect(Collectors.toSet());
使用anyMatch
并没有错,只是用错了地方:
public void deleteRooms() {
rooms = rooms.stream().filter(r -> lamps.stream().map(SmartLamp::getRoom).anyMatch(r::equals);
}
但以上并不理想,因为您必须遍历每个房间的灯列表。预先提取出现在灯列表中的所有房间可以帮助:
public void deleteRooms() {
Set<Room> smartRooms = lamps.stream().map(SmartLamp::getRoom).collect(Collectors.toSet());
rooms = rooms.stream().filter(r -> smartRomms.contains(r)).collect(Collectors.toList());
}
或使用List.removeIf
public void deleteRooms() {
Set<Room> smartRooms = lamps.stream().map(SmartLamp::getRoom).collect(Collectors.toSet());
rooms.removeIf(r -> !smartRomms.contains(r));
}
在下面的练习中,我应该保留所有房间,其中有 SmartLamps。我怎样才能用流解决这个问题?由于每个 SmartLamp 都有 Room 属性,我需要在房间和灯上进行流式传输。我试着用 anyMatch 来做,但找不到可行的解决方案。有人可以帮忙吗? (我知道不用流怎么解决)
public class SmartHome {
private final List<Room> rooms;
private final List<SmartLamp> lamps;
public void deleteRooms() {
rooms.stream().anyMatch(lamps.stream().map(SmartLamp::getRoom));
}
}
代码报错: “类型不匹配:无法从 Stream 转换为 Predicate super Room>”
lamps.stream().map(SmartLamp::getRoom).anyMatch(rooms::contains);
谓词不需要流,您需要创建一个 lambda room -> ...
。
但是您已经必须为映射灯创建一个流,所以我将从该流开始。确实contains
不是很好,但也够精致了。
一个Set<Room>
会更好
我相信任何匹配都不是您想要的。任何匹配都是一种流方法,如果流中的任何内容与您想要的匹配,则 returns true 或 false。
但是不管你想要一个 Predicate
其形式为
List<Room> lampRoomList = lamps.stream().map(SmartLamp::getRoom).ToList()
//predicate is in the filter method
List<Room> roomsWithLamps = rooms.stream().filter(room.toroom -> lampRoomList.Contains(Room)).toList();
第二行中的 room 表示流中的对象。在你的情况下是一个房间。
第一行是保存 lamps 中所有房间的列表,因此您不需要为每个房间映射。
您可以在此处阅读有关谓词的更多信息 https://www.geeksforgeeks.org/java-8-predicate-with-examples/
I should keep all the Rooms, which have SmartLamps in it.
好的,所以你可以这样做...
public class SmartHome {
private final List<Room> rooms;
private final List<SmartLamp> lamps;
void deleteRoomsWithoutSmartLamps() {
var goodRooms = roomsWithSmartLamps();
// This line will remove the bad rooms from the list
rooms = rooms.stream().filter( r -> goodRooms.contains(r)).collect(toList())
}
// This method gives you a list of rooms with smart lamps
public List<Room> roomsWithSmartLamps() {
var goodRooms = lamps.stream().filter( lamp -> lamp.isSmartLamp() ).map(lamp -> lamp.getRoom()).filter(room != null)collect(toList());
return goodRooms;
}
}
这是否解决了您的问题?评论告诉我吧。
你可以试试
lamps.stream()
.map(SmartLamp::getRoom)
.filter(rooms::contains)
.collect(Collectors.toSet());
使用anyMatch
并没有错,只是用错了地方:
public void deleteRooms() {
rooms = rooms.stream().filter(r -> lamps.stream().map(SmartLamp::getRoom).anyMatch(r::equals);
}
但以上并不理想,因为您必须遍历每个房间的灯列表。预先提取出现在灯列表中的所有房间可以帮助:
public void deleteRooms() {
Set<Room> smartRooms = lamps.stream().map(SmartLamp::getRoom).collect(Collectors.toSet());
rooms = rooms.stream().filter(r -> smartRomms.contains(r)).collect(Collectors.toList());
}
或使用List.removeIf
public void deleteRooms() {
Set<Room> smartRooms = lamps.stream().map(SmartLamp::getRoom).collect(Collectors.toSet());
rooms.removeIf(r -> !smartRomms.contains(r));
}