我怎样才能用流解决以下练习

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

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));
}