Hello I have two List of object like this:
List<RoomEntity> RoomsList1 = getAllRooms1();
List<RoomEntity> RoomsList2 = getAllRooms2();
These RoomEntity have an attribute call roomName.
I want to create a new List<RoomEntity> RoomsList3
with all the rooms of RoomsList1 which have the same name in RoomsList2.
I have a method called
.getRoomName()
Something like
RoomsList1 = {RoomEntity[roomName:kitchen, size:10], RoomEntity[roomName:bedroom, size:8]}
RoomsList2 = {RoomEntity[roomName:kitchen, size:15], RoomEntity[roomName:livingroom, size:12]}
then
RoomsList3 = {RoomEntity[name:kitchen, size:10]}
I hope this is clear.
Thanks for your answers.
CodePudding user response:
It can be solved in two ways:
Method 1
List<RoomEntity> roomEntities1 = Arrays.asList(new RoomEntity("kitchen", 10), new RoomEntity("bedroom", 8));
List<RoomEntity> roomEntities2 = Arrays.asList(new RoomEntity("kitchen", 12), new RoomEntity("livingroom", 12));
ArrayList<RoomEntity> roomEntities3 = new ArrayList<>();
for (RoomEntity roomEntity : roomEntities1) {
for (RoomEntity entity : roomEntities2) {
if (entity.getRoomName().equals(roomEntity.getRoomName())) {
roomEntities3.add(roomEntity);
break;
}
}
}
Method 2
List<RoomEntity> roomEntities1 = Arrays.asList(new RoomEntity("kitchen", 10), new RoomEntity("bedroom", 8));
List<RoomEntity> roomEntities2 = Arrays.asList(new RoomEntity("kitchen", 12), new RoomEntity("livingroom", 12));
ArrayList<RoomEntity> roomEntities3 = new ArrayList<>();
HashSet<String> roomNames = new HashSet<>(); // to store all the room name of roomEntities2
for (RoomEntity roomEntity : roomEntities2) {
roomNames.add(roomEntity.getRoomName());
}
for (RoomEntity roomEntity : roomEntities1) {
if (roomNames.contains(roomEntity.getRoomName())) {
roomEntities3.add(roomEntity);
}
}
Note: Method 2 is more efficient on time but requires extra space.
CodePudding user response:
Set<String> setName = new HashSet<>();
RoomEntity2.forEach(entity -> setName.add(entity.getRoomName()));
List<RoomEntity> RoomEntity3 = new ArrayList<>();
RoomEntity1.forEach(entity -> {
if (setName.contains(entity.getRoomName()))
RoomEntity3.add(entity);
});
CodePudding user response:
You can use Stream
Like
List<room> list3 = list1.stream().filter(room ->
list2.stream().anyMatch(room1 ->room1.roomName.equals(room.roomName)))
.collect(Collectors.toList());
If you're not familiar with stream, I'll explain:
First step is filtering the first list it is like an iterator that will say if you want this iteration or not. (.filter())
Second step is looking in the second list if there is a match for an expression (here if room's name from the first list equals any room's name from the second list). (.anymatch())
Third and last step is to collect the result. (.Collectors.toList())
CodePudding user response:
With the proper RoomEntity
implementation (hashCode
and equals
implemented for roomName
), you can reduce the code way more. All you really need is:
List<RoomEntity> rooms1 = new ArrayList<>();
List<RoomEntity> rooms2 = new ArrayList<>();
rooms1.retainAll(rooms2);
#retainAll()
keeps only the entities which are present in both lists. It compares entities using the equals()
method.
Here is a full example code:
public class Test {
public static void main(String[] args) throws ParseException {
List<RoomEntity> rooms1 = new ArrayList<>();
List<RoomEntity> rooms2 = new ArrayList<>();
List<RoomEntity> rooms3 = new ArrayList<>();
Collections.copy(rooms3, rooms1); // only necessary if you don't want to change rooms1
rooms1.retainAll(rooms2);
}
}
class RoomEntity {
private String roomName;
public String getRoomName() {
return roomName;
}
public void setRoomName(String roomName) {
this.roomName = roomName;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result ((roomName == null) ? 0 : roomName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RoomEntity other = (RoomEntity) obj;
if (roomName == null) {
if (other.roomName != null)
return false;
} else if (!roomName.equals(other.roomName))
return false;
return true;
}
}