我有一个与Java 8中的lambda表达式相关的问题。
考虑以下Message
类:
public class Message implements MessageBase
{
private String id;
private String message;
private String author;
private Long timestamp;
public Message()
{
this.id=null;
this.message=null;
this.author=null;
this.timestamp= null;
}
public Message(String id, String message,String author,Long timestamp)
{
this.id=id;
this.message=message;
this.author=author;
this.timestamp= timestamp;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public String getMessage()
{
return message;
}
public void setMessage(String message)
{
this.message = message;
}
public String getAuthor()
{
return author;
}
public void setAuthor(String author)
{
this.author = author;
}
public long getTimestamp()
{
return timestamp;
}
public void setTimestamp(long timestamp)
{
this.timestamp = timestamp;
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof Message))
return false;
Message message1 = (Message) o;
if (getTimestamp() != message1.getTimestamp())
return false;
if (!getId().equals(message1.getId()))
return false;
if (!getMessage().equals(message1.getMessage()))
return false;
return getAuthor().equals(message1.getAuthor());
}
@Override
public int hashCode()
{
int result = getId().hashCode();
result = 31 * result + getMessage().hashCode();
result = 31 * result + getAuthor().hashCode();
result = 31 * result + (int) (getTimestamp() ^ (getTimestamp() >>> 32));
return result;
}
@Override
public String toString()
{
return "id=" + id +
", message='" + message + '\'' +
", author='" + author + '\'' +
", timestamp=" + timestamp;
}
实现MessageBase
接口。我将Message
类的对象存储在TreeMap
- Map<Long, Message> messages
中。键是时间戳,值是Message
对象。我必须按作者查找所有TreeMap
个条目,这是Message
类的字段。我正在尝试使用lambda表达式。
这是我的代码:
messages.entrySet().stream().filter(o->o.getValue().getAuthor().equalsIgnoreCase(author)).findAny();
使用此代码我只能获得一个条目。你能帮我看一下通过过滤器的所有条目的列表吗?
答案 0 :(得分:8)
findAny
最多只返回一个条目。您应该将流收集到Collection
或Map
以获取所有条目:
Map<Long, Message> filteredMessages =
messages.entrySet()
.stream()
.filter(o->o.getValue().getAuthor().equalsIgnoreCase(author))
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
或
List<Map.Entry<Long, Message>> filteredMessages =
messages.entrySet()
.stream()
.filter(o->o.getValue().getAuthor().equalsIgnoreCase(author))
.collect(Collectors.toList());
答案 1 :(得分:0)
另一种方法是按作者对所有Message
个实例进行分组:
Map<String, List<Message>> byAuthor = messages.values().stream()
.collect(Collectors.groupingBy(Message::getAuthor));
这将为每位作者创建一个消息列表。
如果您还需要按作者分组原始地图的键,则可以使用groupingBy()
方法的重载版本,这样您可以保留原始条目:
Map<String, Map<Long, Message>> byAuthor = messages.entrySet().stream()
.collect(Collectors.groupingBy(
e -> e.getValue().getAuthor(),
Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
这里正在创建地图地图,并且流式传输条目(而不仅仅是值,如第一个示例中所示)。第一个地图按作者分组,而第二个地图是原始地图的子地图,仅包含与相应作者匹配的条目。