Skip to content

Instantly share code, notes, and snippets.

@ondrej-kvasnovsky
Created February 7, 2017 06:23
Show Gist options
  • Save ondrej-kvasnovsky/05225306195f8cac8f9ce1567ada37b3 to your computer and use it in GitHub Desktop.
Save ondrej-kvasnovsky/05225306195f8cac8f9ce1567ada37b3 to your computer and use it in GitHub Desktop.
Search.java
package com.kangoapp.view.search;
import java.util.ArrayList;
import java.util.List;
import java.util.function.IntPredicate;
import java.util.stream.IntStream;
import static org.apache.commons.lang3.StringUtils.containsIgnoreCase;
/**
* New instance of search for each search.
*/
public class Search {
private static Search CACHE = new Search("", "");
private final String text;
private final String search;
private int[] rows;
private int[][] columns;
private int rowIndex;
private int columnIndex;
public Search(String text, String search) {
this.text = text;
this.search = search;
}
public static Search search(String text, String search) {
if (!(CACHE.text.equals(text) && CACHE.search.equals(search))) {
CACHE = new Search(text, search);
CACHE.execute();
}
return CACHE;
}
private void execute() {
String[] lines = text.split(System.lineSeparator());
IntPredicate containsIgnoreCase = i -> containsIgnoreCase(lines[i], search);
rows = IntStream.range(0, lines.length)
.filter(containsIgnoreCase)
// .peek(System.out::println)
.toArray();
columns = new int[rows.length][];
int foundMatchIndex = 0;
while (rows.length != 0 && foundMatchIndex < rows.length) {
int foundMatch = rows[foundMatchIndex];
String currentLine = lines[foundMatch];
List<Integer> inLineMatches = new ArrayList<>();
int index = -1;
while ((index = currentLine.indexOf(search, index + 1)) >= 0) {
inLineMatches.add(index);
}
int[] inline = new int[inLineMatches.size()];
for (int i = 0; i < inLineMatches.size(); i++) {
Integer inLineMatch = inLineMatches.get(i);
inline[i] = inLineMatch;
}
columns[foundMatchIndex] = inline;
foundMatchIndex++;
}
}
public Record next() {
int[] column = columns[rowIndex];
if (columnIndex >= column.length) {
columnIndex = 0;
rowIndex++;
}
int row = rows[rowIndex];
column = columns[rowIndex];
return new Record(row, column[columnIndex++]);
}
public boolean hasNext() {
if (rowIndex >= rows.length) {
// start over
rowIndex = 0;
columnIndex = 0;
}
return rows.length != 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment