【问题标题】:Map.Entry interface in javajava中的Map.Entry接口
【发布时间】:2026-01-25 09:15:03
【问题描述】:
java.util.Map.Entry 据我所知是public static interface 在java.util 包中
返回地图的集合视图,但到目前为止我对静态界面感到困惑
因为它是 Map.Entry,它是一个内部接口,如果是这样,我们如何在 java 中拥有内部静态接口
看看我很困惑的人请以任何可能的方式帮助我。
【问题讨论】:
标签:
java
collections
frameworks
【解决方案1】:
Entry 的定义恰好存在于Map 的定义中(java 允许)。成为static 意味着您不需要Map 的实例来引用Entry。
通过一个例子来展示如何使用Map.Entry 是最简单的。这是您可以迭代地图的方法
Map<Integer, String> map = new HashMap<Integer, String>();
for (Map.Entry<Integer, String> entry : map.entrySet()) {
Integer key = entry.getKey();
String value = entry.getValue();
// do something with key and/or value etc
// you may also alter the entry's value inside this loop via entry.setValue()
}
【解决方案2】:
其实没什么好纠结的。
是的,Java 允许接口成为类或其他接口的成员。
不,这并不意味着什么特别。它完全没有改变您如何使用这样的界面或您可以用它做什么。
它只会更改该接口的名称,并在它与其封闭类型之间创建一个强大的概念链接。在这种情况下,Map.Entry 表示 Map 的条目。 API 的设计者显然认为通过将其设为成员类型来强调这种联系是有意义的。
【解决方案3】:
是的,它是Map 接口的内部接口。
/**
* A map entry (key-value pair). The <tt>Map.entrySet</tt> method returns
* a collection-view of the map, whose elements are of this class. The
* <i>only</i> way to obtain a reference to a map entry is from the
* iterator of this collection-view. These <tt>Map.Entry</tt> objects are
* valid <i>only</i> for the duration of the iteration; more formally,
* the behavior of a map entry is undefined if the backing map has been
* modified after the entry was returned by the iterator, except through
* the <tt>setValue</tt> operation on the map entry.
*
* @see Map#entrySet()
* @since 1.2
*/
interface Entry<K,V> {
/**
* Returns the key corresponding to this entry.
*
* @return the key corresponding to this entry
* @throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
K getKey();
/**
* Returns the value corresponding to this entry. If the mapping
* has been removed from the backing map (by the iterator's
* <tt>remove</tt> operation), the results of this call are undefined.
*
* @return the value corresponding to this entry
* @throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
V getValue();
/**
* Replaces the value corresponding to this entry with the specified
* value (optional operation). (Writes through to the map.) The
* behavior of this call is undefined if the mapping has already been
* removed from the map (by the iterator's <tt>remove</tt> operation).
*
* @param value new value to be stored in this entry
* @return old value corresponding to the entry
* @throws UnsupportedOperationException if the <tt>put</tt> operation
* is not supported by the backing map
* @throws ClassCastException if the class of the specified value
* prevents it from being stored in the backing map
* @throws NullPointerException if the backing map does not permit
* null values, and the specified value is null
* @throws IllegalArgumentException if some property of this value
* prevents it from being stored in the backing map
* @throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
V setValue(V value);
/**
* Compares the specified object with this entry for equality.
* Returns <tt>true</tt> if the given object is also a map entry and
* the two entries represent the same mapping. More formally, two
* entries <tt>e1</tt> and <tt>e2</tt> represent the same mapping
* if<pre>
* (e1.getKey()==null ?
* e2.getKey()==null : e1.getKey().equals(e2.getKey())) &&
* (e1.getValue()==null ?
* e2.getValue()==null : e1.getValue().equals(e2.getValue()))
* </pre>
* This ensures that the <tt>equals</tt> method works properly across
* different implementations of the <tt>Map.Entry</tt> interface.
*
* @param o object to be compared for equality with this map entry
* @return <tt>true</tt> if the specified object is equal to this map
* entry
*/
boolean equals(Object o);
/**
* Returns the hash code value for this map entry. The hash code
* of a map entry <tt>e</tt> is defined to be: <pre>
* (e.getKey()==null ? 0 : e.getKey().hashCode()) ^
* (e.getValue()==null ? 0 : e.getValue().hashCode())
* </pre>
* This ensures that <tt>e1.equals(e2)</tt> implies that
* <tt>e1.hashCode()==e2.hashCode()</tt> for any two Entries
* <tt>e1</tt> and <tt>e2</tt>, as required by the general
* contract of <tt>Object.hashCode</tt>.
*
* @return the hash code value for this map entry
* @see Object#hashCode()
* @see Object#equals(Object)
* @see #equals(Object)
*/
int hashCode();
}
有关接口的更多信息,请参阅Interfaces 教程和这篇Static Nested Interfaces 文章。
【解决方案4】:
例子:
public class Outer {
public interface Bar {
Bar get();
}
}
Bar 是一个嵌套界面。嵌套接口默认是静态的,所以你也可以这样写:
public class Outer {
public static interface Bar {
Bar get();
}
}
现在,这个上下文中的静态意味着接口是静态成员,即类的成员。
你也可以用类来做到这一点:
public class Tree {
private static class Node {
}
}
在这里,Node 甚至是私有的,这意味着它只在 Tree 中可见。那么,这样做有什么好处呢?为什么不让 Node 成为一个公共类呢?因为更好的封装。首先,节点是树的一个实现细节,所以你不希望它是可见的。其次,如果您通过公共 API 公开 Node,则某些客户端(程序员)可以在他的代码中使用它。现在,他对这个班级有很强的依赖。如果在某些时候您想更改树的表示,并且更改/删除 Node 类,则客户端代码可能会中断。最后但并非最不重要的一点是,您的公共 API 变得更小,这也是可取的。
那么,什么时候使用静态成员类/接口呢?大多数情况下,如果您构建某种复合对象(如树或链接列表),或者当类仅在外部类的上下文中有意义时。
【解决方案5】:
Java 允许nested interfaces。您可以将它们嵌套到类或接口中。例如,Map.Entry 是在Map 接口中定义的嵌套接口。
Map implementations (TreeMap, HashMap) 提供 Map.Entry 的私有实现,在类外不可见。
Bohemian's answer地址如何使用Map.Entry。
【解决方案6】:
内部接口是隐式公共和静态的。
你可以有如下内部接口:
1. interface A {
.....
.....
interface B {
....
....
}
}
2. class A {
....
....
interface B {
....
....
}
}
你可以通过A.B访问上面的内部接口(B),其中A是根据上面两种情况的类或接口。
例如,
class x implements A.B
{
....
....
}