与通过调用{{1}创建的HashMap
对象相比,NetBeans在将{em>键值对放入HashMap
时往往会修改键值对的顺序直接和javac.exe
。
考虑以下类定义(省略java.exe
和package
声明):
import
直接从Windows命令行编译和运行上面的代码(Java ver.1.8.0_066)产生了这个:
class Coder {
enum Gender { FEMALE, MALE }
String name;
Gender gender;
Coder(String name, Gender gender) {
this.name = name;
this.gender = gender;
}
String getName() { return name; }
Gender getGender() { return gender; }
}
class Test{
public static void main(String[] args) {
List<Coder> list = Arrays.asList(
new Coder("Alice", Coder.Gender.FEMALE),
new Coder("Chuck", Coder.Gender.MALE),
new Coder("Bob", Coder.Gender.MALE));
Map<Coder.Gender, List<String>> classification = list.stream()
.collect(Collectors.groupingBy(Coder::getGender,
Collectors.mapping(Coder::getName, Collectors.toList())));
System.out.println(classification);
// Getting metainfo:
System.out.println("Actual map's type at runtime is " +
classification.getClass().getSimpleName());
System.out.println("OS: " + System.getProperty("os.name") +
", ver." + System.getProperty("os.version"));
System.out.println("Java ver.: " + System.getProperty("java.version"));
// Serializing:
String filename = "classification_cmd.ser";
// String filename = "classification_NetBeans.ser"; // toggle commenting-out as needed
File file = new File(filename);
try (
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream outs = new ObjectOutputStream(fos)
)
{ outs.writeObject(classification);
} catch (IOException ioe) { ioe.printStackTrace(); };
}
}
在我的Raspberry Pi上的CLI(Java ver.1.80_065)和通过ideone.com(Java ver.1.8.0_112)的Linux下,结果基本相同:第一个MALE组,然后是FEMALE一个。但是,在Windows下的NetBeans 8.1(Java ver.1.8.0_066)中,输出相反:
{MALE=[Chuck, Bob], {FEMALE=[Alice]}
在所有情况下,相关地图的实际类型为{FEMALE=[Alice], MALE=[Chuck, Bob]}
。将地图序列化到磁盘并在内部偷看确认对象在键值对的顺序方面确实不同:
因此我的问题是:
HashMap
构建的TreeMap
等),以确保结果完全相同,无论我们如何从命令行或NetBeans中编译和运行我们的程序?答案 0 :(得分:0)
无法保证常规Map实现保留添加元素的任何顺序。
如果你关心那个顺序,你需要使用像TreeMap这样的NavigableMap来保持按键的顺序。您通常不需要提供比较器,如果没有给出,它会使用键类型的自然顺序。