Я построил довольно простую программу, которая берет информацию из файла .txt
и помещает ее в список, сортирует ее, а затем удаляет дубликаты, помещая ее в TreeSet
.Удалите необходимость перебора списка для каждого элемента.
Если посмотреть на countInstance()
и как это называется, вы увидите, что для каждой итерации TreeSet
метод запуска, а затем он перебирает список по dataToSplit
несколько раз. Я считаю, что он повторяет список 30 раз в этом конкретном случае.
Вопрос
Есть ли способ удалить необходимость повторного итерации списка столько раз и при этом достичь тех же результатов?
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class TallyCounter {
private void tallyCount(File commaSeperated) {
List<String> dataToSplit = new ArrayList<String>();
Set<String> set;
try {
BufferedReader br = new BufferedReader(new FileReader(commaSeperated));
String currentLine;
while ((currentLine = br.readLine()) != null) {
String[] tempArray = currentLine.split(",");
for(String s : tempArray) {
dataToSplit.add(s.replaceAll("\t", "").replaceAll("\n", "").trim());
}
}
br.close();
} catch(Exception e) {
e.printStackTrace();
}
dataToSplit.sort(new AlphanumComparator());
set = new TreeSet<String>(dataToSplit);
System.out.println("String Tally Count");
for(String s : set) {
System.out.println(countInstance(s, dataToSplit));
}
}
private String countInstance(String s, List<String> l) {
int count = 0;
for(String temp : l) {
if(s.equals(temp)) {
count++;
}
}
int rSpace = (10 - count)/2;
String repeated = new String(new char[count]).replace("\0", "|");
String space = new String(new char[rSpace]).replace("\0", " ");
return " " + s + " " + space + repeated + " " + space + Integer.toString(count);
}
public static void main(String[] args) {
TallyCounter tC = new TallyCounter();
tC.tallyCount(new File("src/txt.txt"));
}
}
Дополнительные детали
AlphanumComparator.java
import java.util.Comparator;
public class AlphanumComparator implements Comparator<Object>
{
private final boolean isDigit(char ch)
{
return ch >= 48 && ch <= 57;
}
/** Length of string is passed in for improved efficiency (only need to calculate it once) **/
private final String getChunk(String s, int slength, int marker)
{
StringBuilder chunk = new StringBuilder();
char c = s.charAt(marker);
chunk.append(c);
marker++;
if (isDigit(c))
{
while (marker < slength)
{
c = s.charAt(marker);
if (!isDigit(c))
break;
chunk.append(c);
marker++;
}
} else
{
while (marker < slength)
{
c = s.charAt(marker);
if (isDigit(c))
break;
chunk.append(c);
marker++;
}
}
return chunk.toString();
}
public int compare(Object o1, Object o2)
{
if (!(o1 instanceof String) || !(o2 instanceof String))
{
return 0;
}
String s1 = (String)o1;
String s2 = (String)o2;
int thisMarker = 0;
int thatMarker = 0;
int s1Length = s1.length();
int s2Length = s2.length();
while (thisMarker < s1Length && thatMarker < s2Length)
{
String thisChunk = getChunk(s1, s1Length, thisMarker);
thisMarker += thisChunk.length();
String thatChunk = getChunk(s2, s2Length, thatMarker);
thatMarker += thatChunk.length();
// If both chunks contain numeric characters, sort them numerically
int result = 0;
if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0)))
{
// Simple chunk comparison by length.
int thisChunkLength = thisChunk.length();
result = thisChunkLength - thatChunk.length();
// If equal, the first different number counts
if (result == 0)
{
for (int i = 0; i < thisChunkLength; i++)
{
result = thisChunk.charAt(i) - thatChunk.charAt(i);
if (result != 0)
{
return result;
}
}
}
} else
{
result = thisChunk.compareTo(thatChunk);
}
if (result != 0)
return result;
}
return s1Length - s2Length;
}
}
txt.txt
5.00, 5.14, 5.01, 4.90, 5.02, 5.18, 5.04, 5.07, 4.95, 5.05
5.05, 4.82, 4.97, 5.04, 4.98, 5.12, 5.08, 4.96, 5.02, 4.93
5.12, 5.04, 5.13, 4.94, 5.06, 5.00, 4.92, 5.17, 5.08, 4.99
5.07, 5.15, 5.01, 4.95, 5.11, 5.22, 5.08, 4.86, 4.97, 5.14
5.03, 5.14, 5.06, 4.88, 4.96, 5.04, 4.96, 5.09, 4.93, 5.03
сноска
Я извиняюсь за то, как странно выглядит результат, когда он запускается. Это связано только с тем, что я еще не реализовал JTable
для хранения информации.
Я считаю себя потерял, как к тому, что вы пытаетесь сделать, и какой формат вашего вклада. – Zircon
Не совсем ответ на ваш вопрос, поскольку он уже был дан ответ, но нет необходимости подсчитывать частоту элемента в списке. Рамка коллекций уже предоставляет метод для этого: Collections.frequency. Не то чтобы вы могли использовать его в этом случае. – Renatols
@Renatols Спасибо за информацию, но я знал об этом методе. Проблема с его использованием заключается в том, что он выполняет итерацию списка, как моя, поэтому она может быть немного более эффективной, чем моя версия, но не сильно – Dan