Last active
February 12, 2020 22:10
-
-
Save dag05ru/5667dfe8e3338f85ecadc125663abc5d to your computer and use it in GitHub Desktop.
This file contains 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
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.concurrent.ConcurrentHashMap; | |
import java.util.concurrent.ConcurrentLinkedQueue; | |
import java.util.stream.Collectors; | |
public class FastSplitter { | |
// Очищаем и делим строку на списки строк за один проход | |
public List<List<String>> splitAndClear(String input) { | |
List<List<String>> result = new ArrayList<>(); | |
boolean prevIsW = false; | |
boolean newLine = true; | |
StringBuilder word = new StringBuilder(); | |
List<String> line = new ArrayList<>(); | |
for(int i = 0; i < input.length(); i++){ | |
if(newLine) line = new ArrayList<>(); | |
char c = input.charAt(i); | |
if(Character.isLetterOrDigit(c)) { | |
newLine = false; | |
if (!prevIsW) { | |
word = new StringBuilder(); | |
word.append(c); | |
prevIsW = true; | |
} else { | |
word.append(c); | |
} | |
if(i == input.length() - 1) { | |
line.add(word.toString()); | |
} | |
} else { | |
newLine = false; | |
if(prevIsW) { | |
line.add(word.toString()); | |
} | |
if((c == '\n' || i == input.length() - 1) && !line.isEmpty()) { | |
result.add(line); | |
newLine = true; | |
} | |
prevIsW = false; | |
} | |
} | |
return result; | |
} | |
// вычисляем hashcode от массива | |
public int calcHashCode(List<String> strings) { | |
final int prime = 31; | |
int result = 1; | |
List<String> sortedStrs = strings.stream().sorted().collect(Collectors.toList()); | |
for( String s : sortedStrs ) | |
{ | |
result = result * prime + s.hashCode(); | |
} | |
return result; | |
} | |
// В реальном проекте я бы не стал так писать, | |
// но на тестовое задание я не готов тратить много времени. | |
public void createGroups(String input) { | |
ConcurrentHashMap<Integer, ConcurrentLinkedQueue<List<String>>> queue = new ConcurrentHashMap<>(); | |
splitAndClear(input) | |
.parallelStream() | |
.forEach( x -> { | |
synchronized (this) { | |
int key = calcHashCode(x); | |
if (queue.containsKey(key)) { | |
queue.get(key).add(x); | |
} else { | |
ConcurrentLinkedQueue<List<String>> lists = new ConcurrentLinkedQueue<>(); | |
lists.add(x); | |
queue.put(key, lists); | |
} | |
} | |
}); | |
queue.values().stream().forEach(g -> { | |
g.stream().forEach(list -> { | |
System.out.println(list.stream().collect(Collectors.joining(", "))); | |
}); | |
System.out.println("--------------------"); | |
}); | |
} | |
// тест | |
public static void main(String[] args) { | |
String data ="раз,2, три,\n" + | |
"елочка, гори!\n" + | |
"три, 2, раз...\n" + | |
"лысый дикобраз\n" + | |
"***\n"; | |
StringBuilder sb = new StringBuilder(); | |
for(int i = 0; i < 100; i++) { | |
sb.append(data); | |
} | |
String bigLine = sb.toString(); | |
long start = System.currentTimeMillis(); | |
new FastSplitter().createGroups(bigLine); | |
System.out.println("fast1: " + (System.currentTimeMillis() - start)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment