【发布时间】:2018-04-16 11:20:29
【问题描述】:
我目前正在查看两个非常大的Peak 对象列表,方法是重写equals 方法并循环遍历这两个列表,将每个峰值与其他峰值进行比较。有没有更有效的方法来做到这一点?我的列表可以是 ~10,000 个元素,这意味着最多 10000 * 10000 次比较。
我的峰值对象的代码:
public class Peak extends Object{
private final SimpleIntegerProperty peakStart;
private final SimpleIntegerProperty peakEnd;
private final SimpleIntegerProperty peakMaxima;
private final SimpleIntegerProperty peakHeight;
private final SimpleIntegerProperty peakWidth;
private final SimpleStringProperty rname;
public Peak(int peakStart, int peakEnd, int peakMaxima, int peakHeight, String rname) {
this.peakStart = new SimpleIntegerProperty(peakStart);
this.peakEnd = new SimpleIntegerProperty(peakEnd);
this.peakMaxima = new SimpleIntegerProperty(peakMaxima);
this.peakHeight = new SimpleIntegerProperty(peakHeight);
this.peakWidth = new SimpleIntegerProperty(peakEnd - peakStart);
this.rname = new SimpleStringProperty(rname);
}
public String getRname() {
return rname.get();
}
public SimpleStringProperty rnameProperty() {
return rname;
}
public int getPeakWidth() {
return peakWidth.get();
}
public int getPeakHeight() {
return peakHeight.get();
}
public int getPeakStart() {
return peakStart.get();
}
public int getPeakEnd() {
return peakEnd.get();
}
public int getPeakMaxima() {
return peakMaxima.get();
}
@Override
public String toString() {
return "Peak{" +
"peakStart= " + peakStart.get() +
", peakEnd= " + peakEnd.get() +
", peakHeight= " + peakHeight.get() +
", rname= " + rname.get() +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Peak peak = (Peak) o;
if (!peakMaxima.equals(peak.peakMaxima)) return false;
return rname.equals(peak.rname);
}
@Override
public int hashCode() {
int result = peakMaxima.hashCode();
result = 31 * result + rname.hashCode();
return result;
}
}
我比较对象的循环在这里。
List<Peak> interestingPeaks = new ArrayList<>();
if(peakListOne != null && peakListTwo != null){
for(Peak peak : peakListOne){
for(Peak peak2 : peakListTwo){
if(peak.equals(peak2)){ //number one, check the rnames match
if((peak2.getPeakHeight() / peak.getPeakHeight() >= 9) || (peak.getPeakHeight() / peak2.getPeakHeight() >= 9)){
interestingPeaks.add(peak);
}
}
}
}
}
return interestingPeaks;
代码基本上匹配最大值的位置,以及 rname ,它只是一个字符串。然后将峰值附加到interestingPeaks 列表中,如果一个的高度比另一个大 9 倍。
【问题讨论】:
-
你尝试过使用哈希吗?
-
如果您对列表进行排序,您可以更智能地进行比较。
-
有些我们不知道的情况可能会使您的算法更简单或更困难。列表可以排序还是顺序很重要?单个列表中是否允许重复峰值(可能是 HashSet)?有许多算法可以帮助你,但你必须看看可能的方法是否符合你的具体情况。
-
列表未按输入排序,但没有理由不能将它们作为方法的一部分进行排序。
标签: java performance