Created
          February 7, 2017 06:23 
        
      - 
      
- 
        Save ondrej-kvasnovsky/05225306195f8cac8f9ce1567ada37b3 to your computer and use it in GitHub Desktop. 
    Search.java
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | 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