使用lambda表达式由值类的成员搜索TreeMap

时间:2016-02-15 09:37:17

标签: java collections lambda java-8 java-stream

我有一个与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();

使用此代码我只能获得一个条目。你能帮我看一下通过过滤器的所有条目的列表吗?

2 个答案:

答案 0 :(得分:8)

findAny最多只返回一个条目。您应该将流收集到CollectionMap以获取所有条目:

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

这里正在创建地图地图,并且流式传输条目(而不仅仅是值,如第一个示例中所示)。第一个地图按作者分组,而第二个地图是原始地图的子地图,仅包含与相应作者匹配的条目。