1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package de.fu_berlin.ties.classify.feature;
23
24 import org.apache.commons.lang.builder.ToStringBuilder;
25
26 /***
27 * An abstract base class for immutable feature representation used for
28 * classification.
29 *
30 * @author Christian Siefkes
31 * @version $Revision: 1.2 $, $Date: 2004/05/31 19:13:49 $, $Author: siefkes $
32 */
33 public abstract class Feature {
34
35 /***
36 * An optional comment on this feature, ignored for classification.
37 */
38 private final String comment;
39
40 /***
41 * Creates a new instance, without storing a comment.
42 */
43 public Feature() {
44 this(null);
45 }
46
47 /***
48 * Creates a new instance.
49 *
50 * @param myComment a comment on this feature, ignored for classification;
51 * might be <code>null</code>
52 */
53 public Feature(final String myComment) {
54 super();
55 comment = myComment;
56 }
57
58 /***
59 * Indicates whether some other object is "equal to" this one, fulfulling
60 * the {@link Object#equals(java.lang.Object)} contract. To be considered
61 * equal, the object must be a {@link Feature}. If the
62 * {@linkplain #getRepresentation() representation} of this instance is not
63 * <code>null</code>, the representations of the two features are compared.
64 * Otherwise the {@linkplain #getFullRepresentation() full representations}
65 * are compared. Thus for normal features comments and other fields will
66 * be ignored. For comment-only features, comments will be considered,
67 * other fields will be ignored.
68 *
69 * @param obj the reference object with which to compare
70 * @return <code>true</code> iff the specified object is a
71 * {@link Feature} equal to this instance
72 */
73 public boolean equals(final Object obj) {
74 if (obj == this) {
75 return true;
76 } else if (obj instanceof Feature) {
77 final Feature other = (Feature) obj;
78 final String myRep = getRepresentation();
79 if (myRep != null) {
80
81 return myRep.equals(other.getRepresentation());
82 } else {
83
84 return getFullRepresentation().equals(
85 other.getFullRepresentation());
86 }
87 } else {
88 return false;
89 }
90 }
91
92 /***
93 * Returns the comment attached to this feature, if any.
94 *
95 * @return the comment, or <code>null</code> is no comment was stored
96 */
97 public String getComment() {
98 return comment;
99 }
100
101 /***
102 * Prints a full representation of this feature that contains both
103 * representation (if any) and comment (if any). The comment is preceded
104 * by a "#" character.
105 *
106 * @return the full representation
107 */
108 public String getFullRepresentation() {
109 return getFullRepresentation("#");
110 }
111
112 /***
113 * Prints a full representation of this feature that contains both
114 * representation (if any) and comment (if any). The comment is preceded by
115 * the specified <code>separator</code> (surrounded by spaces).
116 *
117 * @param separator used to introduce the comment
118 * @return the full representation
119 */
120 public String getFullRepresentation(final String separator) {
121 final StringBuffer result = new StringBuffer();
122 final String representation = getRepresentation();
123 if ((representation != null) && (representation.length() > 0)) {
124 result.append(representation);
125 }
126
127 if ((comment != null) && (comment.length() > 0)) {
128 if (result.length() > 0) {
129 result.append(' ');
130 }
131 result.append(separator).append(' ').append(comment);
132 }
133 return result.toString();
134 }
135
136 /***
137 * Abstract method for returning the representation of this feature, to be
138 * used for classification.
139 *
140 * @return the feature representation, or <code>null</code> if this feature
141 * contains only a comment
142 */
143 public abstract String getRepresentation();
144
145 /***
146 * Returns a strength value for this feature. This method can be
147 * overwritten to assign higher strenghts to more important or more frequent
148 * features. This implementation always returns 1.0.
149 *
150 * <p>Typically you should call {@link FeatureVector#strength(Feature)}
151 * instead of this method to allow feature vectors to modify the strenghts
152 * of the stored features.
153 *
154 * @return a strength value for this feature -- 1.0 in this implementation
155 */
156 public float getStrength() {
157 return 1.0f;
158 }
159
160 /***
161 * Returns a hash code value for this object, fulfulling the
162 * {@link Object#hashCode()} contract.
163 * @return a hash code value for this object
164 */
165 public int hashCode() {
166 final String myRep = getRepresentation();
167 if (myRep != null) {
168
169 return myRep.hashCode();
170 } else {
171
172 return getFullRepresentation().hashCode();
173 }
174 }
175
176 /***
177 * Returns a string representation of this object.
178 *
179 * @return a textual representation
180 */
181 public String toString() {
182 final ToStringBuilder builder = new ToStringBuilder(this);
183 if ((comment != null) && (comment.length() > 0)) {
184 builder.append("comment", comment);
185 }
186 return builder.toString();
187 }
188
189 }