gpt4 book ai didi

java map 删除意外行为

转载 作者:搜寻专家 更新时间:2023-11-01 02:09:28 25 4
gpt4 key购买 nike

代码:

public class FeatureBuilder implements IFeatureBuilder {

private final Map< java.awt.Shape, ShapeAttributes > shapes = new HashMap<>();

[...]

@Override
public void addToContainer( java.awt.Shape shape ) {
System.err.println( shape.getClass());
shapes.put( shape, new ShapeAttributes( ... ));
}

@Override
public void removeFromContainer( double x, double y ) {
final Set< Shape > rm = new HashSet<>();
final Point2D loc = new Point2D.Double( x, y );
for( final Shape shape : shapes.keySet()) {
if( shape.contains( loc )) {
System.err.println( "shapes.containsKey( shape ): " +
shapes.containsKey( shape ));
rm.add( shape );
}
}
System.err.println( "cardinality before removal : " + shapes.size());
shapes.keySet().removeAll( rm );
System.err.println( "cardinality after removal : " + shapes.size());
}

输出:

class java.awt.geom.Rectangle2D$Double
shapes.containsKey( shape ): false <<<<<<< This is unexpected!
cardinality before removal : 1
rm cardinality : 1
cardinality after removal : 1

我很惊讶:Map.keySet() 上的 for 迭代器检索到的实例不是 Map 中的键!

这怎么可能?

此方法中的主要错误是放置在 rm 中的选定 Shape 实例不会从 shapes 中删除。

阅读您的答案后,代码变为:

public class DecoratedShape {

public final Shape _shape;
public /* */ Color _stroke = Color.BLACK;
public /* */ float _strokeWidth = 3.0f;
public /* */ Color _fill = Color.BLACK;

public DecoratedShape( Shape shape, Color stroke, float strokeWidth, Color fill ) {
_shape = shape;
_stroke = stroke;
_strokeWidth = strokeWidth;
_fill = fill;
}

public boolean contains( Point2D loc ) {
return _shape.contains( loc );
}

public void paint( Graphics2D g ) {
g.setStroke( new BasicStroke( _strokeWidth ));
g.setColor( _fill );
g.fill( _shape );
g.setColor( _stroke );
g.draw( _shape );
}
}

public class FeatureBuilder implements IFeatureBuilder {

private final List< DecoratedShape > _shapes = new LinkedList<>();
[...]

@Override
public void addToContainer( Object o ) {
_shapes.add( new DecoratedShape((Shape)o, _stroke, _strokeWidth, _fill ));
}

@Override
public void removeFromContainer( double x, double y ) {
final Set<DecoratedShape> rm = new HashSet<>();
final Point2D loc = new Point2D.Double( x, y );
for( final DecoratedShape shape : _shapes ){
if( shape.contains( loc ) ){
rm.add( shape );
}
}
_shapes.removeAll( rm );
}

public void paint( Graphics2D g ) {
for( final DecoratedShape shape : _shapes ) {
shape.paint( g );
}
}
}

现在,它按预期工作...非常感谢!

最佳答案

跟进@RohitJain 的评论,这是一个重现该行为的简单示例:

Map<Shape, Object> map = new HashMap<>();
java.awt.geom.Rectangle2D.Double shape = new java.awt.geom.Rectangle2D.Double(1, 1, 1, 1);
map.put(shape, null);
System.out.println(map.size()); //1
shape.setRect(2, 2, 2, 2); //mutate
System.out.println(map.size()); //still 1
map.keySet().remove(shape);
System.out.println(map.size()); //still 1

潜在的问题是 Shape 在 map 中发生了变化。

关于java map 删除意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21096512/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com