使用Java从文本文件创建数据结构

时间:2015-03-19 21:59:53

标签: java arrays file text data-structures

我有一个看起来像这样的文件:

User -> Artist
u1 -> a1
u1 -> a15
u1 -> a123
u2 -> a1
u2 -> a32
...
u1800 -> a56

告诉我们每个用户都听过哪些艺术家。

如何在二维数组(或者可能是另一个更合适的数据结构?)中导入它,其中每一行都是用户,每个[row] [column]用户已经听过的一个艺术家?

我想最终存储u1已收听{a1, a15, a123}

3 个答案:

答案 0 :(得分:3)

您可以将此信息存储在Map中。假设您有一个User课程和一个Artist课程,您可以创建一个Map<User, Set<Artist>>,为每个用户创建一个艺术家集合(或列表,如果您愿意)。

要创建地图,请执行以下操作:

Map<User, Set<Artist>> artistsFromUser = new HashMap<>();

如果您只需要将用户名和艺术家姓名存储为字符串,那么您的地图可以是:

Map<String, Set<String>> artistsFromUser = new HashMap<>();

然后,您需要浏览文件,将每个user -> artist对转换为user对象和artist对象。之后,您可以使用相应的artist引用存储user

// Retrieve the set of artists for this user
// Substitute String for Artist here if you're just storing the names
Set<Artist> artists = artistsFromUser.get(user);
if (artists == null) {
    // If the set was not created for this user yet
    // you need to create it and store it in the map
    artists = new HashSet<>();
    artistsFromUser.put(user, artists);
}
// Add the new artist to the set
artists.add(artist);

打印输出就像执行以下操作一样简单:

System.out.println(user + " has listened to " + artistsFromUser.get(user));

答案 1 :(得分:2)

将您的文件读入List<String>后,它就是一行内容:

Map<String, List<String>> map = lines.stream()
    .map(s -> s.split(" -> "))
    .collect(Collectors.groupingBy(a -> a[0]))
    .entries().stream()
    .toMap(e -> e.getKey(), e -> e.getValue().stream()
        .map(a -> a[1]).collect(Collectors.toList()));

免责声明:手机上的代码翻译 - 可能包含语法错误

答案 2 :(得分:0)

Google Guava Multimap是此的确切结构。 Multimap<K, V>在概念上与Map<K, Collection<V>>相同,这就是您想要的。

特别是,ListMultimap对您的情况非常理想。你可以混合使用Guava和amp; Java 8满足您的要求:

public class FileParser {

    public static void main(String[] args) throws IOException {

        // Path to file
        Path path = Paths.get("fileparser-test.txt");

        // Process file line by line, skipping first
        // one and splitting to get user and artist
        Iterator<String[]> splittedLinesIterator = 
                Files.lines(path).skip(1).
                map(s -> s.split(" -> ")).iterator();

        // Create multimap, indexing by the first element of array
        ListMultimap<String, String[]> multimap = 
                Multimaps.index(splittedLinesIterator, s -> s[0]);

        // Transform values by only keeping second element of array
        ListMultimap<String, String> result = 
                Multimaps.transformValues(multimap, s -> s[1]);

        System.out.println(result); // {u1=[a1, a15, a123], u2=[a1, a32]}
    }
}

请参阅Files.lines()Multimaps.index()Multimaps.transformValues()文档以获取进一步的参考。