Revision 22508 branches/v2_0_0_prep/libraries/libIverUtiles/src/com/iver/utiles/search/BinarySearchUsingFirstCharacters.java

View differences:

BinarySearchUsingFirstCharacters.java
53 53
 * This class has static methods that return items that their beginning text value matches with a text pattern. <br>
54 54
 * It's necessary that items of the parameter array (Vector) were sort ordered according to their text value. <br>
55 55
 * Supports Vectors with and without repeated items.
56
 * 
56
 *
57 57
 * There are four methods, that are a modification of a binary search algorithm of search, getting a rank of items:
58 58
 * <ul>
59 59
 * <li>Considering case sensitive in the search.</li>
......
61 61
 * <li>Considering case sensitive in the search and an object which implements the Comparable interface</li>
62 62
 * <li>Ignoring case sensitive in the search, but yes an objecth which implements the Comparable interface</li>
63 63
 * </ul>
64
 * 
64
 *
65 65
 * @author Pablo Piqueras Bartolom? (pablo.piqueras@iver.es)
66 66
 */
67 67
public class BinarySearchUsingFirstCharacters {
68 68
	/**
69 69
	 * This method should be used when is wanted to distinguish small letters from capital letters during the search.
70
	 *   
70
	 *
71 71
	 * It's necessary that all items of the array implement the {@link Comparable} interface.<br>
72
	 * And it's also necessary that the value returned by the <i>toString()</i> method of each item (supposing 
72
	 * And it's also necessary that the value returned by the <i>toString()</i> method of each item (supposing
73 73
	 *   they inherit from Object) would be the expected value user saw (that would be used to compare the items).
74
	 *   
74
	 *
75 75
	 * @param text java.lang.String
76 76
	 * @param sortOrderedItems java.util.Vector
77 77
	 */
78
	public synchronized static List<Object> doSearchConsideringCaseSensitive(String text, Vector<Object> sortOrderedItems) {
78
	public synchronized static List doSearchConsideringCaseSensitive(String text, Vector sortOrderedItems) {
79 79
		int currentIteration = 0;
80 80
		int size = sortOrderedItems.size();
81 81
		int maxNumberOfIterations = (int) MathExtension.log2(size);
82 82
		int lowIndex = 0;
83 83
		int highIndex = sortOrderedItems.size() - 1;
84 84
		int mIndx;
85
		
85

  
86 86
		while ((lowIndex <= highIndex) && (currentIteration <= maxNumberOfIterations)) {
87 87
			mIndx = ( lowIndex + highIndex ) / 2;
88
			
88

  
89 89
			if ( sortOrderedItems.get( mIndx ).toString().startsWith( text ) ) {
90 90
				lowIndex = highIndex = mIndx;
91 91
				highIndex ++;
......
101 101
				}
102 102

  
103 103
				// It's possible that items with different case, should be between the same case, then this item will be added individually:
104
				List<Object> list = new Vector<Object>(sortOrderedItems.subList(lowIndex, highIndex));
105
				
104
				List list = new Vector(sortOrderedItems.subList(lowIndex, highIndex));
105

  
106 106
				// Expand to down
107 107
				lowIndex --;
108 108
				while ( ( lowIndex > -1 ) && ( sortOrderedItems.get( (lowIndex ) ).toString().toLowerCase().startsWith( text.toLowerCase() ) ) ) {
109 109
					if (sortOrderedItems.get( lowIndex ).toString().startsWith( text )) {
110 110
						list.add(0, sortOrderedItems.get( lowIndex ));
111 111
					}
112
					
112

  
113 113
					lowIndex --;
114 114
				}
115
				
115

  
116 116
				// Expand to up
117 117
				while ( ( highIndex < size ) && ( sortOrderedItems.get( highIndex ).toString().toLowerCase().startsWith( text.toLowerCase() ) ) ) {
118
					if (sortOrderedItems.get( highIndex ).toString().startsWith( text )) {						
118
					if (sortOrderedItems.get( highIndex ).toString().startsWith( text )) {
119 119
						list.add(list.size(), sortOrderedItems.get( highIndex ));
120 120
					}
121
					
121

  
122 122
					highIndex ++;
123 123
				}
124
				
124

  
125 125
				// Returns all items in the rank
126 126
				return list; // Breaks the loop
127 127
			}
......
133 133
					lowIndex = mIndx + 1;
134 134
				}
135 135
			}
136
			
136

  
137 137
			currentIteration ++;
138 138
		}
139
		
139

  
140 140
		// If no item has been found -> return null
141 141
		return null;
142 142
	}
143
	
143

  
144 144
	/**
145 145
	 * This method should be used when is wanted not to distinguish small letters from capital letters during the search.
146
	 *   
146
	 *
147 147
	 * It's necessary that all items of the array implement the {@link Comparable} interface.<br>
148
	 * And it's also necessary that the value returned by the <i>toString()</i> method of each item (supposing 
148
	 * And it's also necessary that the value returned by the <i>toString()</i> method of each item (supposing
149 149
	 *   they inherit from Object) would be the expected value user saw (that would be used to compare the items).
150 150
	 *
151 151
	 * In this particular situation, it's supposed that the vector is sort ordered according the default algorithm of Java; this has the problem that
......
156 156
	 * @param text java.lang.String
157 157
	 * @param sortOrderedItems java.util.Vector
158 158
	 */
159
	public synchronized static List<Object> doSearchIgnoringCaseSensitive(String text, Vector<Object> sortOrderedItems) {
159
	public synchronized static List doSearchIgnoringCaseSensitive(String text, Vector sortOrderedItems) {
160 160
		int currentIteration = 0;
161 161
		int size = sortOrderedItems.size();
162 162
		int maxNumberOfIterations = (int) MathExtension.log2(size);
163 163
		int lowIndex = 0;
164 164
		int highIndex = sortOrderedItems.size() - 1;
165 165
		int mIndx;
166
		List<Object> list = null;
167
		List<Object> list2 = null;
166
		List list = null;
167
		List list2 = null;
168 168

  
169 169
		// FIRST RANK
170 170
		while ((lowIndex <= highIndex) && (currentIteration <= maxNumberOfIterations)) {
171 171
			mIndx = ( lowIndex + highIndex ) / 2;
172
			
172

  
173 173
			if ( sortOrderedItems.get( mIndx ).toString().toLowerCase().startsWith( text.toLowerCase() ) ) {
174 174
				lowIndex = highIndex = mIndx;
175 175
				highIndex ++;
176
				
176

  
177 177
				// Expand the rank to up
178 178
				while ( ( highIndex < size ) && ( sortOrderedItems.get( highIndex ).toString().toLowerCase().startsWith( text.toLowerCase() ) ) ) {
179 179
					highIndex ++;
......
183 183
				while ( ( (lowIndex - 1) > -1 ) && ( sortOrderedItems.get( (lowIndex - 1) ).toString().toLowerCase().startsWith( text.toLowerCase() ) ) ) {
184 184
					lowIndex --;
185 185
				}
186
				
186

  
187 187
				// Returns all items in the rank
188 188
				list = Arrays.asList((sortOrderedItems.subList(lowIndex, highIndex)).toArray());
189 189
				break;
......
196 196
					lowIndex = mIndx + 1;
197 197
				}
198 198
			}
199
			
199

  
200 200
			currentIteration ++;
201 201
		}
202 202

  
......
207 207

  
208 208
		while ((lowIndex <= highIndex) && (currentIteration <= maxNumberOfIterations)) {
209 209
			mIndx = ( lowIndex + highIndex ) / 2;
210
			
210

  
211 211
			if ( sortOrderedItems.get( mIndx ).toString().toLowerCase().startsWith( text.toLowerCase() ) ) {
212 212
				lowIndex = highIndex = mIndx;
213 213
				highIndex ++;
214
				
214

  
215 215
				// Expand the rank to up
216 216
				while ( ( highIndex < size ) && ( sortOrderedItems.get( highIndex ).toString().toLowerCase().startsWith( text.toLowerCase() ) ) ) {
217 217
					highIndex ++;
......
221 221
				while ( ( (lowIndex - 1) > -1 ) && ( sortOrderedItems.get( (lowIndex - 1) ).toString().toLowerCase().startsWith( text.toLowerCase() ) ) ) {
222 222
					lowIndex --;
223 223
				}
224
				
225
				// Returns all items in the rank			
224

  
225
				// Returns all items in the rank
226 226
				list2 = Arrays.asList((sortOrderedItems.subList(lowIndex, highIndex)).toArray()); // Breaks the loop
227
				
227

  
228 228
				if (list == null)
229 229
					return list2;
230 230
				else {
......
233 233

  
234 234
					Object obj;
235 235
					int j;
236
					
237
					list = new ArrayList<Object>(list.subList(0, list.size()));
238
					
236

  
237
					list = new ArrayList(list.subList(0, list.size()));
238

  
239 239
					for (int i = 0; i < list2.size(); i ++) {
240 240
						obj = list2.get(i);
241
					
241

  
242 242
						// Don't add items which are already in the list
243
						if (!list.contains(obj)) {		
243
						if (!list.contains(obj)) {
244 244
							// Adds in sort order the new item:
245 245
							for (j = 0; j < list.size(); j ++) {
246 246
								if (list.get(j).toString().compareTo(obj.toString()) > 0)
247 247
									break;
248 248
							}
249
							
249

  
250 250
							list.add(j, obj);
251 251
						}
252 252
					}
253
					
253

  
254 254
					// It's possible that some elements at the end wouldn't be found -> another small search
255 255
					size = list.size();
256 256
					if (size == 0) {
......
259 259
					else {
260 260
						j = sortOrderedItems.indexOf(list.get(size - 1));
261 261
					}
262
					
262

  
263 263
					j++;
264
					
264

  
265 265
					if (j < sortOrderedItems.size()) {
266 266
						do {
267 267
							obj = sortOrderedItems.get( j );
268
							
268

  
269 269
							if (obj.toString().toLowerCase().startsWith( text.toLowerCase())) {
270 270
								list.add(size, obj);
271 271
							}
272
							
272

  
273 273
							j++;
274 274
						}
275 275
						while (j < sortOrderedItems.size());
276 276
					}
277
					
277

  
278 278
					return list;
279 279
				}
280 280
			}
......
286 286
					lowIndex = mIndx + 1;
287 287
				}
288 288
			}
289
			
289

  
290 290
			currentIteration ++;
291 291
		}
292
		
292

  
293 293
		return null;
294 294
	}
295
	
295

  
296 296
//	/** THIS VERSION FAILURES IN SOME PARTICULAR SITUATIONS
297 297
//	 * This method should be used when is wanted distinguish small letters from capital letters during the search, and the comparation of items
298 298
//	 *   done according an algorithm we define.
299
//	 *   
300
//	 * And it's also necessary that the value returned by the <i>toString()</i> method of each item (supposing 
299
//	 *
300
//	 * And it's also necessary that the value returned by the <i>toString()</i> method of each item (supposing
301 301
//	 *   they inherit from Object) would be the expected value user saw (that would be used to compare the items).
302
//	 *   
302
//	 *
303 303
//	 * @param text java.lang.String
304 304
//	 * @param sortOrderedItems java.util.Vector
305 305
//	 * @param comp An Comparator object which implements the <i><b>compareTo()</b><i>  method.
......
332 332
//
333 333
//				// It's possible that items with different case, should be between the same case, then this item will be added individually:
334 334
//				List list = new Vector(sortOrderedItems.subList(lowIndex, highIndex));
335
//				
336 335
//
336
//
337 337
//				// Expand to down
338 338
//				lowIndex --;
339 339
//				while ( ( lowIndex > -1 ) && ( sortOrderedItems.get( (lowIndex ) ).toString().toLowerCase().startsWith( text.toLowerCase() ) ) ) {
340 340
//					if (sortOrderedItems.get( lowIndex ).toString().startsWith( text )) {
341 341
//						list.add(0, sortOrderedItems.get( lowIndex ));
342 342
//					}
343
//					
343
//
344 344
//					lowIndex --;
345 345
//				}
346
//				
346
//
347 347
//				// Expand to up
348 348
//				while ( ( highIndex < size ) && ( sortOrderedItems.get( highIndex ).toString().toLowerCase().startsWith( text.toLowerCase() ) ) ) {
349
//					if (sortOrderedItems.get( highIndex ).toString().startsWith( text )) {						
349
//					if (sortOrderedItems.get( highIndex ).toString().startsWith( text )) {
350 350
//						list.add(list.size(), sortOrderedItems.get( highIndex ));
351 351
//					}
352
//					
352
//
353 353
//					highIndex ++;
354 354
//				}
355
//				
355
//
356 356
//				// Returns all items in the rank
357 357
//				return list; // Breaks the loop
358 358
//			}
......
371 371
//		// If no item has been found -> return null
372 372
//		return null;
373 373
//	}
374
	
374

  
375 375
	/**
376 376
	 * This method should be used when is wanted distinguish small letters from capital letters during the search, and the comparation of items
377 377
	 *   done according an algorithm we define.
378
	 *   
379
	 * And it's also necessary that the value returned by the <i>toString()</i> method of each item (supposing 
378
	 *
379
	 * And it's also necessary that the value returned by the <i>toString()</i> method of each item (supposing
380 380
	 *   they inherit from Object) would be the expected value user saw (that would be used to compare the items).
381
	 *   
381
	 *
382 382
	 * @param text java.lang.String
383 383
	 * @param sortOrderedItems java.util.Vector
384 384
	 * @param comp An Comparator object which implements the <i><b>compareTo()</b><i>  method.
385 385
	 */
386
	public synchronized static List<Object> doSearchConsideringCaseSensitive(String text, Vector<Object> sortOrderedItems, Comparator<Object> comp) {
387
		List<Object> results_list = doSearchIgnoringCaseSensitive(text, sortOrderedItems, comp);
386
	public synchronized static List doSearchConsideringCaseSensitive(String text, Vector sortOrderedItems, Comparator comp) {
387
		List results_list = doSearchIgnoringCaseSensitive(text, sortOrderedItems, comp);
388 388

  
389 389
		if (results_list == null)
390 390
			return null;
391 391

  
392
		List<Object> results = new ArrayList<Object>();
392
		List results = new ArrayList();
393 393

  
394 394
		for (int i = 0; i < (results_list.size()); i++) {
395 395
			if (results_list.get(i).toString().startsWith(text)) {
......
399 399

  
400 400
		return results;
401 401
	}
402
	
402

  
403 403
	/**
404 404
	 * This method should be used when is wanted not to distinguish small letters from capital letters during the search, and the comparation of items
405 405
	 *   done according an algorithm we define.
406
	 *   
407
	 * And it's also necessary that the value returned by the <i>toString()</i> method of each item (supposing 
406
	 *
407
	 * And it's also necessary that the value returned by the <i>toString()</i> method of each item (supposing
408 408
	 *   they inherit from Object) would be the expected value user saw (that would be used to compare the items).
409 409
	 *
410 410
	 * @param text java.lang.String
411 411
	 * @param sortOrderedItems java.util.Vector
412 412
	 * @param comp An Comparator object which implements the <i><b>compareTo()</b><i>  method.
413 413
	 */
414
	public synchronized static List<Object> doSearchIgnoringCaseSensitive(String text, Vector<Object> sortOrderedItems, Comparator<Object> comp) {
414
	public synchronized static List doSearchIgnoringCaseSensitive(String text, Vector sortOrderedItems, Comparator comp) {
415 415
		int currentIteration = 0;
416 416
		int size = sortOrderedItems.size();
417 417
		int maxNumberOfIterations = (int) MathExtension.log2(size);
418 418
		int lowIndex = 0;
419 419
		int highIndex = sortOrderedItems.size() - 1;
420 420
		int mIndx;
421
		
421

  
422 422
		while ((lowIndex <= highIndex) && (currentIteration <= maxNumberOfIterations)) {
423 423
			mIndx = ( lowIndex + highIndex ) / 2;
424 424

  
425 425
			if ( sortOrderedItems.get( mIndx ).toString().toLowerCase().startsWith( text.toLowerCase() ) ) {
426 426
				lowIndex = highIndex = mIndx;
427 427
				highIndex ++;
428
				
428

  
429 429
				// Expand the rank to up
430 430
				while ( ( highIndex < size ) && ( sortOrderedItems.get( highIndex ).toString().toLowerCase().startsWith( text.toLowerCase() ) ) ) {
431 431
					highIndex ++;
......
435 435
				while ( ( (lowIndex - 1) > -1 ) && ( sortOrderedItems.get( (lowIndex - 1) ).toString().toLowerCase().startsWith( text.toLowerCase() ) ) ) {
436 436
					lowIndex --;
437 437
				}
438
				
439
				// Returns all items in the rank			
438

  
439
				// Returns all items in the rank
440 440
				return Arrays.asList((sortOrderedItems.subList(lowIndex, highIndex)).toArray()); // Breaks the loop
441 441
			}
442 442
			else {
......
447 447
					lowIndex = mIndx + 1;
448 448
				}
449 449
			}
450
			
450

  
451 451
			currentIteration ++;
452 452
		}
453
		
453

  
454 454
		return null;
455 455
	}
456 456
}

Also available in: Unified diff