Java 比较一个ArrayList并合并常用元素

Java 比较一个ArrayList并合并常用元素,java,algorithm,sorting,arraylist,matching,Java,Algorithm,Sorting,Arraylist,Matching,我一直在研究一种算法来循环遍历一个包含自定义对象的ArrayList。我现在已经上了20个小时,几乎什么也没得到 ArrayList<TicketItem> all = new ArrayList<>(); // ... 'all' gets filled here ... // ArrayList<TicketItem> allCopy = new ArrayList<>(all); for (int i =

我一直在研究一种算法来循环遍历一个包含自定义对象的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;
                }
            }
        }
    }
ArrayList all=new ArrayList();
// ... '这里所有的人都被填满了//
ArrayList allCopy=新建ArrayList(全部);
对于(int i=allCopy.size()-1;i>0;i--){
TicketItem last=allCopy.get(i);
对于(int j=0;j
当它想这样做的时候,它就起作用了。老实说,它可能真的很丑。我就是想不出一个更好的选择

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;
}
public boolean可以分组(TicketItem-other){
如果(其他==null)
返回false;
if(getBoolean(票证项\票证项\无效))
返回false;
if(other.getBoolean(TicketItem.TICKET\u ITEM\u VOID))
返回false;
if(getInteger(TicketItem.菜单项)==null)
返回false;
if(getInteger(TicketItem.MENU项).equals(other.getInteger(TicketItem.MENU项))
&&getBigDecimal(票证金额、票证项目总数)。与(
other.getBigDecimal(TicketItem.TICKET\u ITEM\u TOTAL))==0){
ArrayList mThis=getModifiers();
ArrayList mOther=other.getModifiers();
if(mThis==null&&mOther==null)
返回true;
if(mThis!=null&&mOther!=null){
if(mThis.size()==mOther.size()){
对于(int i=0;i
再次强调,超级丑陋,尤其是其中的for循环,它可以在需要时工作。如果需要,我可以为TicketItem和TicketItemModifier这两个类修改hashCode和equals方法,但是我想远离这两个方法,按照可比较类的思路做一些事情,因为它们可以分组并不意味着它们相等


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

我建议您创建一个新的属性或函数,如ticketItemCode,它应该是MENU_ITEM+“-”+TICKET_ITEM_TOTAL+“-”的字符串串联+菜单\修改器\修改器列表中的ID。您可以筛选列表以删除TICKET\u ITEM\u VOID为true的项目,然后按新属性ticketItemCode排序并进行分组。通过这种方式,您可以将时间从n^2减少到nlogn

这是天才,我无法理解为什么我从未想到它,但是,这仍然让我需要修复for循环方法,除非您认为这是唯一的方法。您可以创建额外的字典数据结构,保存键和在该键下找到的第一个对象,这样,您只需要一个循环