Проблемы с текстовыми файлами

#java #data-structures #text #graph

#java #структуры данных #текст #График

Вопрос:

Я не знаю, насколько хорошо я смогу задать этот вопрос, но, учитывая текстовый файл, мне нужно проанализировать и извлечь данные ProductID и сохранить их в HashSet, данные userId и сохранить их в HashSet, а также обзор / оценка и сохранить их в ArrayList. Их также необходимо использовать для создания графика, где идентификатор продукта связан с ребром между идентификатором пользователя.

Данные находятся здесь http://snap.stanford.edu/data/web-FineFoods.html Вы можете игнорировать обзор / время, обзор / полезность, обзор / резюме и обзор / текстовую информацию, их не нужно сохранять в памяти.

Мой текущий код выглядит следующим образом:

 import java.io.*;
import java.util.*;
import java.nio.charset.*;

public class Reviews
{
    String fileName = "newfinefoods.txt";
    GraphType<String> foodReview;
    HashSet<String> productID;
    HashSet<String> userID;
    ArrayList<String> review;
    
    int counter; //was using this to make sure I'm counting all the lines which I think I am
    
    public Reviews(){
        foodReview = new GraphType<>();
        productID = new HashSet<>();
        userID = new HashSet<>();
        review = new ArrayList<>();
        counter = 0;
    }
    
    public int numReviews(){
        return review.size();
    }
    
    public int numProducts(){
        return productID.size();
    }
    
    public int numUsers(){
        return userID.size();
    }
    
    public void setupGraph(){
        Scanner fileScanner;
        String line = "";
        try{
            fileScanner = new Scanner (new File (fileName), "UTF-8");
            String pr = "";
            while(fileScanner.hasNextLine()){
                line = fileScanner.nextLine();
                String[] reviewInfo = line.split(": ");
                String productInfo = reviewInfo[1];
                System.out.println(productInfo);
            }
        }
        
        catch (IOException e){
            System.out.println(e);
        }
    }
    
    
    
    public static void main(String[] args){
        Reviews review = new Reviews();
        review.setupGraph();
        System.out.println("Number of Reviews:"   review.numReviews());
        System.out.println("Number of Products:"   review.numProducts());
        System.out.println("Number of Users:"   review.numUsers());
        
    }
}

 

Всякий раз, когда я запускаю код, просматривая в массиве reviewInfo значение 1, он печатает только один набор данных, но если я изменяю его на 0, кажется, что он печатает всю информацию (только не ту информацию, которая мне нужна). Мне нужно создать этот график и получить информацию из данных, но я действительно просто застрял, и любые советы или помощь будут очень признательны!

Вот пример данных:

 product/productId: B001E4KFG0
review/userId: A3SGXH7AUHU8GW
review/profileName: delmartian
review/helpfulness: 1/1
review/score: 5.0
review/time: 1303862400
review/summary: Good Quality Dog Food
review/text: I have bought several of the Vitality canned dog food products and have found them all to be of good quality. The product looks more like a stew than a processed meat and it smells better. My Labrador is finicky and she appreciates this product better than  most.

product/productId: B00813GRG4
review/userId: A1D87F6ZCVE5NK
review/profileName: dll pa
review/helpfulness: 0/0
review/score: 1.0
review/time: 1346976000
review/summary: Not as Advertised
review/text: Product arrived labeled as Jumbo Salted Peanuts...the peanuts were actually small sized unsalted. Not sure if this was an error or if the vendor intended to represent the product as "Jumbo".

product/productId: B000LQOCH0
review/userId: ABXLMWJIXXAIN
review/profileName: Natalia Corres "Natalia Corres"
review/helpfulness: 1/1
review/score: 4.0
review/time: 1219017600
review/summary: "Delight" says it all
review/text: This is a confection that has been around a few centuries.  It is a light, pillowy citrus gelatin with nuts - in this case Filberts. And it is cut into tiny squares and then liberally coated with powdered sugar.  And it is a tiny mouthful of heaven.  Not too chewy, and very flavorful.  I highly recommend this yummy treat.  If you are familiar with the story of C.S. Lewis' "The Lion, The Witch, and The Wardrobe" - this is the treat that seduces Edmund into selling out his Brother and Sisters to the Witch.

product/productId: B000UA0QIQ
 

Комментарии:

1. Также в текстовом файле есть пустые строки, о которых, как я думаю, мне нужно как-то позаботиться, но я думаю, что это должно быть простое утверждение if, верно?

2. Этот файл, который вы связали, очень большой и его сложно загрузить. Не могли бы вы предоставить образец в своем вопросе?

3. @Cardinal-RestorateMonica да, он был слишком большим для меня, чтобы работать на компьютере ym, lol. только что обновил его, спасибо за совет!

4. Я немного запутался в целевой модели. Вы уверены, что вам нужно хранить данные в двух хэш-наборах и одном ArrayList?

5. @LittleSanti нет, я не уверен, что это то, что я хочу использовать! Я полагал, что HashSet позволит мне хранить идентификаторы пользователей и идентификаторы продуктов и автоматически обрабатывать дубликаты, а затем просто распечатывать размер хэш-наборов (потому что одна из наших задач — показать, сколько уникальных продуктов было просмотрено и сколько уникальных пользователей просмотрели продукты)

Ответ №1:

Первоначальный подход к вашему дизайну правильный, но вам следует немного структурировать его:

Метод setupGraph должен быть разделен на небольшие конкретные и параметризованные методы:

  • Поскольку пользователи и продукты являются частью состояния класса, я считаю, что будет лучше, если конструктор класса получит сканер в качестве входного параметра. Затем, после инициализации переменных состояния, он должен вызывать setupGraph (который должен быть закрытым), передавая сканер ввода.
  • setupGraph должен получить сканер ввода и взять на себя ответственность за чтение строк из него и дать надлежащую обработку IOExceptions, которые могут возникнуть. В каждой строке он должен просто вызывать другой частный метод для обработки прочитанной строки. Если вы хотите подсчитать все прочитанные строки, именно здесь вы должны поместить приращение.
  • Метод строки обработки должен получить входную строку и взять на себя ответственность за принятие решения о том, содержит ли она данные продукта, данные пользователя, данные оценки или нет. Это должно быть сделано путем правильного анализа его содержимого. Вот где вы можете использовать String.split() , чтобы получить имя и значение каждой строки, а затем оценить имя, чтобы решить, где хранить значение. И если вы хотите подсчитать все обработанные строки, именно здесь вы должны поместить приращение.
  • Наконец, main метод должен взять на себя ответственность за создание экземпляра сканера и передачу его при создании объекта Reviews. Таким образом, вы могли бы получать имя файла в качестве входного аргумента из командной строки, чтобы ваша программа стала гибкой.

Поймите, что единственными общедоступными методами вашего класса должны быть конструктор и геттеры. И переменные состояния должны быть частными.