当我从地图检索地图条目时,将其存储在可选中,然后使用remove(entry.getKey())从地图中删除相同的条目,然后可选的突然开始指向地图中可用的下一个地图条目。
让我进一步解释一下:
我有一堆要排序的注释对象。注释列表应始终以被接受为答案的注释开始,它应是列表中的第一个元素。排序方法从一个映射开始,并使用entrySet上的流检索第一条注释,该注释的布尔值设置为true。
Map<Long, CommentDTO> sortedAndLinkedCommentDTOMap = sortCommentsAndLinkCommentRepliesWithOwningComments(commentDTOSet);
Optional<Map.Entry<Long, CommentDTO>> acceptedAnswerCommentOptional = sortedAndLinkedCommentDTOMap.entrySet().stream()
.filter(entry -> entry.getValue().isAcceptedAsAnswer()).findFirst();
假设Map
包含3个id3、6和11
的注释。键始终是注释的id,注释始终是值。标记为答案的注释具有id6
。在这种情况下,执行以下代码:
if(acceptedAnswerCommentOptional.isPresent()){
Map.Entry<Long, CommentDTO> commentDTOEntry = acceptedAnswerCommentOptional.get();
sortedAndLinkedCommentDTOMap.remove(commentDTOEntry.getKey());
}
当使用acceptedAnswerCommentOptional的值初始化commentDTOEntry时,它会引用id为6的已接受答案。现在,当我从SortedAndLinkedCommentDomain映射中删除该条目时,对接受答案注释的引用不仅会从SortedAndLinkedCommentDomain映射中删除,还会从acceptedAnswerCommentOptional中删除!但现在开始指向sortedAndLinkedCommentDTOMap的下一个条目,即带有键11的条目,而不是变为null。
我不明白是什么导致了这种奇怪的行为。为什么acceptedAnswerCommentOptional的值不变成null?为什么当我从地图中删除接受的回答注释时,它不能保持对接受的回答注释的引用?
当使用调试模式在intellij IDEA中运行代码时,您可以自己看到这种行为,只要将删除方法称为注释的解释性调试标签,注释位于接受答案注释可选的旁边-
编辑:我根据WJSs的意愿制作了一个可重复的示例。这是代码:
import java.util.*;
import java.math.BigInteger;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.function.Function;
class CommentDTO implements Comparable<CommentDTO> {
private BigInteger id;
private BigInteger owningCommentId;
private BigInteger commenterId;
private Long owningEntityId;
private String commenterName;
private String commenterRole;
private String country;
private String thumbnailImageUrl;
private String content;
private String commentDateVerbalized;
private boolean flagged;
private Integer flagCount;
private boolean deleted;
private boolean liked;
private Integer likeCount;
private String lastEditedOnVerbalized;
private boolean acceptedAsAnswer;
private boolean rightToLeft;
private TreeSet<CommentDTO> replies = new TreeSet<>();
public CommentDTO() {
}
public CommentDTO(boolean acceptedAsAnswer, BigInteger id){
this.acceptedAsAnswer = acceptedAsAnswer;
this.id = id;
}
public CommentDTO(boolean acceptedAsAnswer, BigInteger id, BigInteger owningCommentId){
this.acceptedAsAnswer = acceptedAsAnswer;
this.id = id;
this.owningCommentId = owningCommentId;
}
public BigInteger getId() {
return id;
}
public void setId(BigInteger id) {
this.id = id;
}
public BigInteger getOwningCommentId() {
return owningCommentId;
}
public void setOwningCommentId(BigInteger owningCommentId) {
this.owningCommentId = owningCommentId;
}
public BigInteger getCommenterId() {
return commenterId;
}
public void setCommenterId(BigInteger commenterId) {
this.commenterId = commenterId;
}
public Long getOwningEntityId() {
return owningEntityId;
}
public void setOwningEntityId(Long owningEntityId) {
this.owningEntityId = owningEntityId;
}
public String getCommenterName() {
return commenterName;
}
public void setCommenterName(String commenterName) {
this.commenterName = commenterName;
}
public String getCommenterRole() {
return commenterRole;
}
public void setCommenterRole(String commenterRole) {
this.commenterRole = commenterRole;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCommentDateVerbalized() {
return commentDateVerbalized;
}
public void setCommentDateVerbalized(String commentDateVerbalized) {
this.commentDateVerbalized = commentDateVerbalized;
}
public boolean isFlagged() {
return flagged;
}
public void setFlagged(boolean flagged) {
this.flagged = flagged;
}
public Integer getFlagCount() {
return flagCount;
}
public void setFlagCount(Integer flagCount) {
this.flagCount = flagCount;
}
public boolean isDeleted() {
return deleted;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
public boolean isLiked() {
return liked;
}
public void setLiked(boolean liked) {
this.liked = liked;
}
public Integer getLikeCount() {
return likeCount;
}
public void setLikeCount(Integer likeCount) {
this.likeCount = likeCount;
}
public TreeSet<CommentDTO> getReplies() {
return replies;
}
public void setReplies(TreeSet<CommentDTO> replies) {
this.replies = replies;
}
public String getLastEditedOnVerbalized() {
return lastEditedOnVerbalized;
}
public void setLastEditedOnVerbalized(String lastEditedOnVerbalized) {
this.lastEditedOnVerbalized = lastEditedOnVerbalized;
}
public String getThumbnailImageUrl() {
return thumbnailImageUrl;
}
public void setThumbnailImageUrl(String thumbnailImageUrl) {
this.thumbnailImageUrl = thumbnailImageUrl;
}
public boolean isAcceptedAsAnswer() {
return acceptedAsAnswer;
}
public void setAcceptedAsAnswer(boolean acceptedAsAnswer) {
this.acceptedAsAnswer = acceptedAsAnswer;
}
public boolean isRightToLeft() {
return rightToLeft;
}
public void setRightToLeft(boolean rightToLeft) {
this.rightToLeft = rightToLeft;
}
@Override
public int compareTo(CommentDTO o) {
return this.id.compareTo(o.id);
}
@Override
public String toString() {
return "CommentDTO{" +
"id=" + id +
", owningCommentId=" + owningCommentId +
", commenterId=" + commenterId +
", owningEntityId=" + owningEntityId +
", commenterName='" + commenterName + '\'' +
", commenterRole='" + commenterRole + '\'' +
", country='" + country + '\'' +
", thumbnailImageUrl='" + thumbnailImageUrl + '\'' +
", content='" + content + '\'' +
", commentDateVerbalized='" + commentDateVerbalized + '\'' +
", flagged=" + flagged +
", flagCount=" + flagCount +
", deleted=" + deleted +
", liked=" + liked +
", likeCount=" + likeCount +
", lastEditedOnVerbalized='" + lastEditedOnVerbalized + '\'' +
", acceptedAsAnswer=" + acceptedAsAnswer +
", rightToLeft=" + rightToLeft +
", replies=" + replies +
'}';
}
}
public class HelloWorld implements Comparable<HelloWorld> {
private Long id;
private boolean acceptedAsAnswer;
public HelloWorld(){}
public HelloWorld(boolean acceptedAsAnswer, Long id){
this.acceptedAsAnswer = acceptedAsAnswer;
this.id = id;
}
@Override
public String toString() {
return "id= " + id + " acceptedAsAnswer= " + acceptedAsAnswer;
}
public boolean isAcceptedAsAnswer(){
return acceptedAsAnswer;
}
public long getId(){
return id;
}
public static void main(String []args){
HelloWorld helloWorld = new HelloWorld();
helloWorld.doTest();
}
@Override
public int compareTo(HelloWorld o) {
return this.id.compareTo(o.id);
}
public void doTest(){
Set<CommentDTO> commentDTOSet = new HashSet<>();
commentDTOSet.add( new CommentDTO(false, BigInteger.valueOf(3)));
commentDTOSet.add( new CommentDTO(true, BigInteger.valueOf(6)));
commentDTOSet.add( new CommentDTO(false, BigInteger.valueOf(11)));
commentDTOSet.add( new CommentDTO(true, BigInteger.valueOf(7), BigInteger.valueOf(6)));
commentDTOSet.add( new CommentDTO(true, BigInteger.valueOf(8), BigInteger.valueOf(6)));
Map<Long, CommentDTO> sortedAndLinkedCommentDTOMap = sortCommentsAndLinkCommentRepliesWithOwningComments(commentDTOSet);
Optional<Map.Entry<Long, CommentDTO>> acceptedAnswerCommentOptional = sortedAndLinkedCommentDTOMap.entrySet().stream()
.filter(entry -> entry.getValue().isAcceptedAsAnswer()).findFirst();
if(acceptedAnswerCommentOptional.isPresent()){
Map.Entry<Long, CommentDTO> commentDTOEntry = acceptedAnswerCommentOptional.get();
System.out.println(commentDTOEntry.toString());
sortedAndLinkedCommentDTOMap.remove(commentDTOEntry.getKey());
System.out.println(commentDTOEntry.toString());
}
}
private Map<Long, CommentDTO> sortCommentsAndLinkCommentRepliesWithOwningComments(Set<CommentDTO> commentDTOSet){
Map<Long, CommentDTO> commentDTOMap = commentDTOSet.stream()
.collect(Collectors.toMap(comment -> comment.getId().longValueExact(), Function.identity(), (v1,v2) -> v1, TreeMap::new));
commentDTOSet.forEach(commentDTO -> {
BigInteger owningCommentId = commentDTO.getOwningCommentId();
if(owningCommentId != null){
CommentDTO owningCommentDTO = commentDTOMap.get(owningCommentId.longValueExact());
owningCommentDTO.getReplies().add(commentDTO);
}
});
commentDTOMap.values().removeIf(commentDTO -> commentDTO.getOwningCommentId() != null);
return commentDTOMap;
}
}
您可以在此处运行上面的代码:https://www.tutorialspoint.com/compile_java_online.php
编辑2:示例代码现在再现了我的问题。
编辑3:这一行代码注释tomap。值()。删除(注释至-
发生这种情况是因为您使用的地图是TreeMap
。
一个TreeMap
实现为红黑树,它是一个自平衡二叉树。
映射的条目用作树的节点。
如果删除一个条目,则树必须重新平衡自身,然后可能会使用该条目来指向替代它的节点。
自树映射。entrySet()由映射支持,更改反映在集合中。
更改还取决于要删除的节点,例如,如果它是一片叶子,那么它可能只是与树断开链接,而条目不受影响。
如果使用另一个map实现,如HashMap,则不会出现这种行为。
顺便说一下,这里有一个更简单的示例,它甚至不涉及可选类或自定义类:
Map<Long, String> map = new TreeMap<>();
map.put(1L, "a");
map.put(2L, "b");
map.put(3L, "c");
map.put(4L, "d");
map.put(5L, "e");
map.put(6L, "f");
Map.Entry<Long, String> entry = map.entrySet().stream()
.filter(e -> e.getKey().equals(4L))
.findFirst()
.get();
System.out.println(entry); // prints 4=d
map.remove(entry.getKey());
System.out.println(entry); // prints 5=e
问题内容: 我需要遍历不知道其参数化类型的映射的条目集。 遍历此类入口集时,为什么不编译呢? 但这编译: 并且也可以编译(由于我不知道地图的类型,所以我不能使用它): 问题答案: 您在第一个错误中遇到的错误是: 这是因为编译器会转换FOR-IN循环: 至: 您的第二个示例有效, 但只能通过作弊! 您正在进行未经检查的演员表转换,以 恢复 到。 成为: 更新资料 如注释中所述,在两个示例中,类型信息
我正在使用AWSJavaSDK的DynamoDBMapper,并处理一个相当简单的项目:它有一个字符串属性(用作哈希键)和一个map属性。 我可以使用和方法读写我的对象。我遇到的问题是,当我需要在映射中为表中的现有项更新或添加单个条目时。在不知道所述项的映射的现有条目的情况下(并且我不想每次尝试更新或添加之前都执行),我似乎能做的最好的事情就是删除整个映射,并用我尝试更新或添加的单个条目替换它。是
问题内容: 有什么办法可以将整个对象放到像这样的对象中: 而不是传递像这样的键值对: 问题答案: 我已经在Map接口方法上进行了搜索,但是没有方法接受一个条目并将其放入地图中。因此,我自己使用一点继承和Java 8接口来实现它。 的接口仅仅是一个扩展的接口通过添加一种以上的方法,该接口。除了仅定义方法外,还对默认实现进行了编码。这样做,我们现在可以通过定义一个新的实现接口的类并扩展我们选择的map
如果我试图在不调用构造函数的情况下创建映射,则该对象不可用: 出于好奇,我想知道条目存储在哪里,但构造函数似乎没有添加属性: 你知道吗?
结果,我收到一个System.io.Exception: npgsql.npgsqlexception(0x80004005):从流中读取时出现异常-->system.io.ioexception:冯·德·贝尔特拉贡斯维宾登·科恩·基恩·达滕·盖勒森·韦登:艾因·维宾登·维萨奇·费尔格斯拉根,达·迪·盖根斯泰尔·纳赫·艾纳·贝斯特姆滕·泽斯潘尼·尼赫特·里希蒂格·雷杰特帽子,奥德·迪·赫尔杰斯特·
给定一个 如何通过流将和的值提取到以下内容中? 我尝试了以下方法,但在获取列表值的部分遇到了问题。