我有CSV文件,我已存储在Google云存储中。我正在阅读这个CSV文件并为每个单词出现构建一个树形图。有没有办法我可以在文件中排序和显示前10个单词?
这是我的代码:
@SuppressWarnings("serial")
public class GoogleCloudStorageServlet extends HttpServlet {
public static final String BUCKETNAME = "bigdata";
public static final String FILENAME = "Railways.csv";
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world from java");
GcsService gcsService = GcsServiceFactory.createGcsService();
GcsFilename filename = new GcsFilename(BUCKETNAME, FILENAME);
GcsFileOptions options = new GcsFileOptions.Builder()
.mimeType("text/html")
.acl("public-read")
.addUserMetadata("myfield1", "my field value")
.build();
GcsOutputChannel writeChannel = gcsService.createOrReplace(filename, options);
PrintWriter writer = new PrintWriter(Channels.newWriter(writeChannel, "UTF8"));
GcsInputChannel readChannel = null;
BufferedReader reader = null;
String cvsSplitBy = ",";
try {
readChannel = gcsService.openReadChannel(filename, 0);
reader = new BufferedReader(Channels.newReader(readChannel, "UTF8"));
String line;
TreeMap<String, Integer> map = new TreeMap<String, Integer>();
while ((line = reader.readLine()) != null) {
String[] post = line.split(cvsSplitBy);
String[] words = post[1].split("[ \n\t\r.,;:!?(){}]");
for (int counter = 0; counter < words.length; counter++) {
String key = words[counter].toLowerCase(); // remove .toLowerCase for Case Sensitive result.
if (key.length() > 0) {
if (map.get(key) == null) {
map.put(key, 1);
}
else {
int value = map.get(key).intValue();
value++;
map.put(key, value);
}
}
}
//Display only top 10 words in the file
}
} finally {
if (reader != null) { reader.close(); }
}
}
}
答案 0 :(得分:2)
计算CSV文件中前10个单词的方法取决于文件的大小。
小文件(可以存储在内存中)
如果是小文件,您可以使用某种针对您的案例优化的集合(例如Bill Lin提到的Multiset)或自行执行计算。
Map<String, Integer> counts = new HashMap<String, Integer>();
for (String word : words) {
Integer count = counts.get(word);
if (count == null) {
counts.put(word, 1);
} else {
counts.put(word, count + 1);
}
}
如果文件非常小,这样的计算可以在单个请求的范围内处理。
中/大尺寸文件
如果是中型或大型文件,您可能会超出请求限制(60秒),也可能耗尽可用内存。它也不会很有效率。你需要一种不同的方法。
MapReduce是一种用于以并行和分布式方式处理大量数据的编程模型。它对于无法在单个请求范围内处理的大型长期运行作业非常有用。
显示结果的方式取决于您的处理模式。
同步
如果您的计算是同步的,您可以通过传递的响应对象直接从Servlet显示结果。
HttpServletResponse#getWriter()
异步
如果是异步计算,您需要将结果存储在某处(例如数据存储区)并按需显示
答案 1 :(得分:1)
我建议你使用 Multiset和Multisets.copyHighestCountFirst
https://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained