简体   繁体   English

比较不同类型的对象列表的有效方法

[英]Efficient way to compare different types of List of Objects

public class State{

String code;
int occurValue;
int name;

}

public class Equi{
String code;
int occurValue;
int macAddress;

}

Having 2 classes of different types. 具有2个不同类型的类别。 I'm having a List<State> and List<equi> . 我有一个List<State>List<equi> In these lists if code and occurValue is same, I need to move that to different List. 在这些列表中,如果代码和existValue相同,则需要将其移至其他列表。 How can I achieve this, googling gave me so many options line Comparable, Comparator. 我怎么能做到这一点,谷歌搜索给了我这么多选择线比较器,比较器。 Let me know which is the most efficient way to achieve this. 让我知道哪种方法最有效。 Thanks in advance. 提前致谢。

I would use an own defined method to do that, a Boolean <compare(State state, Equi equi)> or something like that with the given list items as parameters. 我将使用自己定义的方法来执行此操作,或者使用Boolean <compare(State state, Equi equi)>或类似的方法,将给定的列表项作为参数。 And the code: 和代码:

//You have to iterate the method with a for loop for example
//In different situations you need different iterating methods, for example you add 
//1 element to Equi:
//You compare all State element with the new Equi element, but just with that ONE
for (int i =0; i < stateList.size(); i++ {
  flag = compare(stateList.get(i),equiList.get(<indexOfNewElement>); // flag is a boolean value
  if (flag) {
    //moving metod and stuff...
  }
}
//this way you don't make unnecessary steps. It's one example, there are many other situation

Boolean compare(State state, Equi equi) { // You add List elements as parameters
  if (state.getCode().equals(equi.getCode())) { // I prefer to use getters, it depends on your code and preferences
    if (state.getOccurValue() == equi.getOccurValue()) { //same here
      return true; //If returns true, an other method move it.
    } else {
      return false;
    }
  } else { //if the first ones aren't equal needless to check the second values
    return false;
  }
}

This way you can use this method for all comparison, but every time you need to write an iterator. 这样,您可以使用此方法进行所有比较,但是每次需要编写迭代器时。 It means more coding, but less runtime. 这意味着更多的编码,但运行时间更少。 For example if the lists are ordered by code in ABC order, you can avoid to compare the "k*" with "a*" using a flag or anything. 例如,如果列表按code以ABC顺序排序,则可以避免使用标记或其他任何东西将“ k *”与“ a *”进行比较。

It highly depends on your definition of "efficient". 这在很大程度上取决于您对“效率”的定义。

If you are not interested in time you can just create a double foreach loop and compare each item with each other. 如果您对时间不感兴趣,则可以创建一个双重foreach循环并将每个项目相互比较。 This is brute-force and not time-efficient (as it is O(n^2)) , but saves you a lot of programming time you can spend on something more useful. 这是蛮力的,并且不节省时间(因为它是O(n ^ 2)) ,但是可以节省大量的编程时间,您可以花在一些更有用的东西上。 The same goes with a fairly small number of items (I suggest < 10.000), where time-optimizations usually don't pay of. 数量很少的商品(我建议<10.000)也是如此,而时间优化通常是不付钱的。

If you want it time-efficient you can use some abstract data structure to help you. 如果您希望节省时间,可以使用一些抽象的数据结构来帮助您。 For example if the "code"-field is unique in each set, create a HashMap where the key refers to "code" and the value is the Equi referenct. 例如,如果“代码”字段在每个集合中都是唯一的,则创建一个HashMap ,其中键引用“代码”,并且值是Equi引用。 You can then iterate over your States and query the HashMap for a matching Equi. 然后,您可以遍历您的州,并在HashMap中查询匹配的Equi。 Ask the returned Equi for its occurValue. 向返回的Equi询问发生值。 You may also introduce a second HashMap with the occurValues as keys. 您还可以引入另一个第二个HashMap,其中将elseValues作为键。 This should give you O(n) for the comparison part. 比较部分应为O(n)。

A more object-oriented approach you be to create an interface IHasCodeAndOccurValue and let State and Equi implement it. 您将采用一种更加面向对象的方法来创建接口IHasCodeAndOccurValue,并让State和Equi实现该接口。 Then you implement equals(IHasCodeAndOccurValue other) methods in both classes. 然后在两个类中实现equals(IHasCodeAndOccurValue other)方法。 You insert both data sets in a List each and call stateList.retainAll(equiList). 您将两个数据集都插入到一个List中,然后调用stateList.retainAll(equiList)。 This might be the most elegant approach and - depending on your chosen List implementation - can also run in O(n) . 这可能是最优雅的方法,并且-取决于您选择的List实现- 也可以在O(n)中运行

As you can see, there are several ways of optimizing this code. 如您所见,有几种优化此代码的方法。 Without knowing the details it is pure speculation how to proceed. 不知道细节,纯粹是猜测如何进行。

If there is no additional information on the lists, then the most efficient algorithm is to compare each element of the one list with each element of the other: 如果列表上没有其他信息,那么最有效的算法是将一个列表的每个元素与另一个列表的每个元素进行比较:

for (State s : stateList) {
    for (equi e : equiList) {
        if (s.code.equals(e.code) && s.occurValue == e.occurValue) {
            // add to another list
        }
    }
}

This is O(n * m) (where n is the size of stateList and m is the size of equiList). 这是O(n * m)(其中n是stateList的大小,m是equiList的大小)。

If the two lists are sorted, then more efficient algorithms can be used. 如果对两个列表进行了排序,则可以使用更有效的算法。 For example, in pseudocode: 例如,用伪代码:

for (int i = 0; i < stateList.size(); i++) {
    int j = 0;
    State s = stateList.get(i);
    while (equiList.get(j) is smaller than s) {
        j++;
    }
    equi e = equiList.get(j);
    if (s.code.equals(e.code) && s.occurValue == e.occurValue) {
        // add to another list
    }
}

This is O(m + n). 这是O(m + n)。 Of course, for this to work you will have to write comparison functions (one for comparing a State with a State , one for comparing an equi with an equi and one for comparing a State with an equi ). 当然,要做到这一点,您将必须编写比较功能(一个用于将一个State与一个State进行比较,一个用于将一个equi与一个equi进行比较以及一个用于将一个State与一个equi进行比较的函数)。

By the way, Java naming conventions dictate that classes start with a capital letter, so it should be Equi , not equi . 顺便说一句,Java命名约定规定类以大写字母开头,因此应该为Equi而不是equi

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM