【问题标题】:Compare one ArrayList and combine common elements比较一个 ArrayList 并组合常见元素
【发布时间】:2014-11-18 05:21:20
【问题描述】:

我一直在研究一种算法来循环遍历一个包含自定义对象的 ArrayList。我现在是第 20 个小时,但我几乎一无所获。

    ArrayList<TicketItem> all = new ArrayList<>();

    // ... 'all' gets filled here ... //

    ArrayList<TicketItem> allCopy = new ArrayList<>(all);
    for (int i = allCopy.size() - 1; i > 0; i--) {
        TicketItem last = allCopy.get(i);
        for (int j = 0; j < all.size(); j++) {
            TicketItem compare = all.get(j);
            if (last.getInt(TicketItem.TICKET_ITEM_ID) != compare.getInt(TicketItem.TICKET_ITEM_ID)) {
                if (last.canBeGrouped(compare)) {
                    last.put(TicketItem.TICKET_ITEM_NUMBER, compare.getInteger(TicketItem.TICKET_ITEM_NUMBER));
                    allCopy.set(i, last);
                    break;
                }
            }
        }
    }

这在需要时有效,老实说,它可能真的很难看。我只是想不出更好的选择。

TicketItem里面的重要方法就是这个:

public boolean canBeGrouped(TicketItem other) {
    if (other == null)
        return false;
    if (getBoolean(TicketItem.TICKET_ITEM_VOID))
        return false;
    if (other.getBoolean(TicketItem.TICKET_ITEM_VOID))
        return false;
    if (getInteger(TicketItem.MENU_ITEM) == null)
        return false;
    if (getInteger(TicketItem.MENU_ITEM).equals(other.getInteger(TicketItem.MENU_ITEM))
            && getBigDecimal(TicketItem.TICKET_ITEM_TOTAL).compareTo(
                    other.getBigDecimal(TicketItem.TICKET_ITEM_TOTAL)) == 0) {
        ArrayList<TicketItemModifier> mThis = getModifiers();
        ArrayList<TicketItemModifier> mOther = other.getModifiers();
        if (mThis == null && mOther == null)
            return true;
        if (mThis != null && mOther != null) {
            if (mThis.size() == mOther.size()) {
                for (int i = 0; i < mThis.size(); i++) {
                    TicketItemModifier m1 = mThis.get(i);
                    TicketItemModifier m2 = mOther.get(i);
                    Integer m1MenuModifierId = m1.getInteger(TicketItemModifier.MENU_MODIFIER_ID);
                    Integer m2MenuModifierId = m2.getInteger(TicketItemModifier.MENU_MODIFIER_ID);
                    if (!(m1MenuModifierId != null && m2MenuModifierId != null && m1MenuModifierId
                            .equals(m2MenuModifierId))) {
                        return false;
                    }
                }
                return true;
            }
        }
    }
    return false;
}

再一次,超级丑陋,尤其是其中的 for 循环,它可以在它想要的时候工作。如果需要,我可以修改 TicketItem 和 TicketItemModifier 两个类的 hashCode 和 equals 方法,但是我想远离这两个方法并按照 Comparable 类的方式做一些事情,因为仅仅因为它们可以分组并不意味着它们是相等的.

我想要做的基本上是通过一个 ArrayList 填充 TicketItem 对象,当两个可以分组时,我需要更改 TicketItem 对象以匹配它。

【问题讨论】:

    标签: java algorithm sorting arraylist matching


    【解决方案1】:

    我建议您创建一个新的属性或函数,例如 TickeItemCode,它应该是修饰符列表中 MENU_ITEM+ "-"+ TICKET_ITEM_TOTAL+ "-" + MENU_MODIFIER_IDs 的字符串连接。您可以过滤列表以删除 TICKET_ITEM_VOID 为 true 的项目,然后按新属性 TickeItemCode 排序并进行分组。这样您可以将时间从 n^2 减少到 nlogn

    【讨论】:

    • 这真是天才,为什么我从来没有想过它超出了我的能力范围,但是,这仍然让我修复了 for 循环方法,除非你认为这是唯一的方法。
    • 你可以创建额外的字典数据结构来保存键和在该键下找到的第一个对象,这样你只需要一个循环
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    • 1970-01-01
    • 2016-01-18
    • 1970-01-01
    相关资源
    最近更新 更多