我在Java中使用过HashMap但从未遇到过这种行为。我必须输入项目和项目组。它们的定义如下面的代码片段所示。
public class Item {
String id;
float total;
}
public class ItemGroup {
String keyword;
int frequency;
List<Item> items;
}
所以 ItemGroup 包含0 .. *项目。这些项目具有共同的关键字,并且关键字在系统中以某种频率出现。现在是有趣的部分,我有以下方法,给出一个项目列表创建一个组列表。
public static ItemGroup[] createGroups(Item[] items){
HashMap<String, ItemGroup> groups = new HashMap<String, ItemGroup>();
String[] words;
for (int i=0; i<items.length; i++){
words = items[i].getId().split(REGEX);
// Process keywords
for (int j=0; j<words.length; j++){
if (words[j].isEmpty()) break;
ItemGroup group = groups.get(words[j]);
if (group != null){
group.incrementFrequency();
group.getItems().add(items[i]);
}else {
group = EconomFactory.eINSTANCE.createItemGroup();
group.setKeyword(words[j]);
group.incrementFrequency();
group.getItems().add(items[i]);
groups.put(words[j], group);
}
}
}
return groups.values().toArray(new ItemGroup[0]);
}
奇怪的部分是将项目添加到项目组(行group.getItems()。add(items [i]);)。在重组期间,该团体以一种奇怪的方式丢失了它的物品。使用调试我可以看到该组在操作之后包含该项目,但是后面的项目,例如当返回方法的值时,所有组都丢失了它们的项目。
我试过了:
public static ItemGroup[] createGroups(Item[] items){
HashMap<String, ItemGroup> groups = new HashMap<String, ItemGroup>();
String[] words;
for (int i=0; i<items.length; i++){
words = items[i].getId().split(REGEX);
// Create a new item based on the current one in the list
Item item = EconomFactory.eINSTANCE.createItem();
item.setId(items[i].getId());
item.setTotal(items[i].getTotal());
// Process key words
for (int j=0; j<words.length; j++){
if (words[j].isEmpty()) break;
ItemGroup group = groups.get(words[j]);
if (group != null){
group.incrementFrequency();
group.getItems().add(item);
}else {
group = EconomFactory.eINSTANCE.createItemGroup();
group.setKeyword(words[j]);
group.incrementFrequency();
group.getItems().add(item);
groups.put(words[j], group);
}
}
}
return groups.values().toArray(new ItemGroup[0]);
}
但得到了相同的结果。但是,以下解决方案可以正常工作。
public static ItemGroup[] createGroups(Item[] items){
HashMap<String, ItemGroup> groups = new HashMap<String, ItemGroup>();
String[] words;
for (int i=0; i<items.length; i++){
words = items[i].getId().split(REGEX);
// Process key words
for (int j=0; j<words.length; j++){
if (words[j].isEmpty()) break;
// Create a new item based on the current one in the list
Item item = EconomFactory.eINSTANCE.createItem();
item.setId(items[i].getId());
item.setTotal(items[i].getTotal());
ItemGroup group = groups.get(words[j]);
if (group != null){
group.incrementFrequency();
group.getItems().add(item);
}else {
group = EconomFactory.eINSTANCE.createItemGroup();
group.setKeyword(words[j]);
group.incrementFrequency();
group.getItems().add(item);
groups.put(words[j], group);
}
}
}
return groups.values().toArray(new ItemGroup[0]);
}
方法EconomFactory.eINSTANCE.createItemGroup()实现如下:
public ItemGroup createItemGroup() {
ItemGroupImpl itemGroup = new ItemGroupImpl();
return itemGroup;
}
其中ItemGroupImpl是ItemGroup的实现,e.i。它是ItemGroup的子类。这是因为我使用EMF(Eclipse Modeling Framework)。
任何人都可以解释这种行为(为什么ItemGroup对象丢失了他们的项目)?
以下是ItemGroup和ItemGroupImpl的代码。同样的方式查找Item和ItemImpl的代码。
public interface ItemGroup extends EObject {
String getKeyword();
void setKeyword(String value);
int getFrequency();
void setFrequency(int value);
EList<Item> getItems();
void incrementFrequency();
}
public class ItemGroupImpl extends EObjectImpl implements ItemGroup {
protected static final String KEYWORD_EDEFAULT = null;
protected String keyword = KEYWORD_EDEFAULT;
protected static final int FREQUENCY_EDEFAULT = 0;
protected int frequency = FREQUENCY_EDEFAULT;
protected EList<Item> items;
protected ItemGroupImpl() {
super();
}
@Override
protected EClass eStaticClass() {
return EconomPackage.Literals.ITEM_GROUP;
}
public String getKeyword() {
return keyword;
}
public void setKeyword(String newKeyword) {
String oldKeyword = keyword;
keyword = newKeyword;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET,
EconomPackage.ITEM_GROUP__KEYWORD, oldKeyword, keyword));
}
public int getFrequency() {
return frequency;
}
public void setFrequency(int newFrequency) {
int oldFrequency = frequency;
frequency = newFrequency;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET,
EconomPackage.ITEM_GROUP__FREQUENCY, oldFrequency, frequency));
}
public EList<Item> getItems() {
if (items == null) {
items = new EObjectContainmentEList<Item>(Item.class, this,
EconomPackage.ITEM_GROUP__ITEMS);
}
return items;
}
public void incrementFrequency() {
this.frequency = getFrequency() + 1;
}
@Override
public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID,
NotificationChain msgs) {
switch (featureID) {
case EconomPackage.ITEM_GROUP__ITEMS:
return ((InternalEList<?>)getItems()).basicRemove(otherEnd,
msgs);
}
return super.eInverseRemove(otherEnd, featureID, msgs);
}
@Override
public Object eGet(int featureID, boolean resolve, boolean coreType) {
switch (featureID) {
case EconomPackage.ITEM_GROUP__KEYWORD:
return getKeyword();
case EconomPackage.ITEM_GROUP__FREQUENCY:
return getFrequency();
case EconomPackage.ITEM_GROUP__ITEMS:
return getItems();
}
return super.eGet(featureID, resolve, coreType);
}
@SuppressWarnings("unchecked")
@Override
public void eSet(int featureID, Object newValue) {
switch (featureID) {
case EconomPackage.ITEM_GROUP__KEYWORD:
setKeyword((String)newValue);
return;
case EconomPackage.ITEM_GROUP__FREQUENCY:
setFrequency((Integer)newValue);
return;
case EconomPackage.ITEM_GROUP__ITEMS:
getItems().clear();
getItems().addAll((Collection<? extends Item>)newValue);
return;
}
super.eSet(featureID, newValue);
}
@Override
public void eUnset(int featureID) {
switch (featureID) {
case EconomPackage.ITEM_GROUP__KEYWORD:
setKeyword(KEYWORD_EDEFAULT);
return;
case EconomPackage.ITEM_GROUP__FREQUENCY:
setFrequency(FREQUENCY_EDEFAULT);
return;
case EconomPackage.ITEM_GROUP__ITEMS:
getItems().clear();
return;
}
super.eUnset(featureID);
}
@Override
public boolean eIsSet(int featureID) {
switch (featureID) {
case EconomPackage.ITEM_GROUP__KEYWORD:
return KEYWORD_EDEFAULT == null ? keyword != null :
!KEYWORD_EDEFAULT.equals(keyword);
case EconomPackage.ITEM_GROUP__FREQUENCY:
return frequency != FREQUENCY_EDEFAULT;
case EconomPackage.ITEM_GROUP__ITEMS:
return items != null && !items.isEmpty();
}
return super.eIsSet(featureID);
}
@Override
public String toString() {
if (eIsProxy()) return super.toString();
StringBuffer result = new StringBuffer();
result.append("(keyword: ");
result.append(keyword);
result.append(", frequency: ");
result.append(frequency);
result.append(')');
return result.toString();
}
}
答案 0 :(得分:0)
在你的第二套代码中,我在哪里进行了初始化?
public static ItemGroup[] createGroups(Item[] items){
HashMap<String, ItemGroup> groups = new HashMap<String, ItemGroup>();
String[] words;
// Create a new item based on the current one in the list
Item item = EconomFactory.eINSTANCE.createItem();
item.setId(items[i].getId());
item.setTotal(items[i].getTotal());
变量i尚未在此上下文中初始化,因此它可以是任何值(因为它没有爆炸,我假设你的代码中有一个全局的“i”,而你正在用它开始你的方法值instaed为0.
在您正在运行的代码中,您在访问它之前已在方法中进行了初始化:
public static ItemGroup[] createGroups(Item[] items){
HashMap<String, ItemGroup> groups = new HashMap<String, ItemGroup>();
String[] words;
for (int i=0; i<items.length; i++){
words = items[i].getId().split(REGEX);
// Process key words
for (int j=0; j<words.length; j++){
if (words[j].isEmpty()) break;
所以,这就是为什么你看到你所看到的行为的猜测...在访问它们之前总是初始化变量。
答案 1 :(得分:0)
请告诉我们EconomFactory.eINSTANCE.createItemGroup()中会发生什么?我无法判断每次都是否创建了具有唯一项目列表的唯一实例。
我尝试了一些修改(我目前没有使用Java 6,所以不能使用String.isEmpty)并假设常规对象创建,它适用于我。请参阅下面我的可运行示例(下次您提出问题时应该发布的内容):
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ItemGrouper {
public static class Item {
String id;
float total;
Item(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
public static class ItemGroup {
String keyword;
int frequency;
List<Item> items = new ArrayList<ItemGrouper.Item>();
public void incrementFrequency() {
frequency++;
}
public List<Item> getItems() {
return items;
}
public void setKeyword(String string) {
keyword = string;
}
@Override
public String toString() {
return String.format("key=%s freq=%s", keyword, frequency);
}
}
public static ItemGroup[] createGroups(Item[] items) {
Map<String, ItemGroup> groups = new HashMap<String, ItemGroup>();
String[] words;
for (int i = 0; i < items.length; i++) {
words = items[i].getId().split(" ");
// Process keywords
for (int j = 0; j < words.length; j++) {
if (words[j].length() == 0) {
break;
}
ItemGroup group = groups.get(words[j]);
if (group == null) {
group = new ItemGroup();
group.setKeyword(words[j]);
groups.put(words[j], group);
}
group.incrementFrequency();
group.getItems().add(items[i]);
}
}
return groups.values().toArray(new ItemGroup[0]);
}
public static void main(String[] args) {
Item[] items = new Item[] {new Item("one two"), new Item("two three")};
ItemGroup[] itemgroups = createGroups(items);
System.out.println(Arrays.toString(itemgroups));
}
}
输出:
[key=one freq=1, key=two freq=2, key=three freq=1]