package com.thinkbiganalytics.spark.dataprofiler.topn; /*- * #%L * thinkbig-spark-job-profiler-app * %% * Copyright (C) 2017 ThinkBig Analytics * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import java.io.Serializable; import javax.annotation.Nonnull; /** * Class for an item in Top-N list<br>* */ @SuppressWarnings("serial") public class TopNDataItem implements Serializable, Comparable<TopNDataItem> { private Object value; private Long count; /** * Constructor to create an item * * @param value value of item * @param count frequency of item */ public TopNDataItem(Object value, Long count) { this.value = value; this.count = count; } /** * Get value of item * * @return value */ public Object getValue() { return value; } /** * Set value of item * * @param value item value */ public void setValue(Object value) { this.value = value; } /** * Get frequency of item * * @return count/frequency */ public Long getCount() { return count; } /** * Set frequency of item */ public void setCount(Long count) { this.count = count; } /** * Get verbose description of item */ @Override public String toString() { return "TopNDataItem [value=" + value + ", count=" + count + "]"; } /** * Compare to another item based upon count/frequency * This is used by TreeSet for ordering */ @Override public int compareTo(@Nonnull TopNDataItem other) { /* if count of this item is lower, it is smaller */ if (this.count < other.count) { return -1; } /* if count of this item is higher, it is bigger */ else if (this.count > other.count) { return 1; } /* if both items have same count - 1. if both items have values as null, they are equal - 2. if this item's value is null and other item's value is not null, this item is lower - 3. if this item's value is not null and other item's value is null, this item is higher - 4. if both items have same non-null values, they are equal. - 5. if both items have different non-null values, consider this item as lower. (favors keeping non-null items seen earlier) */ else if (this.count.equals(other.count)) { //1 if ((this.value == null) && (other.value == null)) { return 0; } //2 else if (this.value == null) { return -1; } //3 else if (other.value == null) { return 1; } //4 else if (this.value.equals(other.value)) { return 0; } //5 else { return -1; } } return -1; } /** * Generate hashCode for item */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((count == null) ? 0 : count.hashCode()); result = prime * result + ((value == null) ? 0 : value.hashCode()); return result; } /** * Equality check logic to determine if item is equal to another item */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } TopNDataItem other = (TopNDataItem) obj; if (count == null) { if (other.count != null) { return false; } } else if (!count.equals(other.count)) { return false; } if (value == null) { if (other.value != null) { return false; } } else if (!value.equals(other.value)) { return false; } return true; } }