从 Java 中的文本文件创建数据结构

Create Data-Structure from text file in Java

我有一个如下所示的文件:

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

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

我如何将其导入二维数组(或者可能是另一个更合适的数据结构?),其中每一行都是一个用户,每一[行][列]是用户拥有的一位艺术家听了吗?

我想结束存储 u1 听过 {a1, a15, a123} 等等

您可以将此信息存储在 Map 中。假设您有一个 User class 和一个 Artist class,您可以创建一个 Map<User, Set<Artist>> 来保留一组(如果您愿意,也可以列出)艺术家对于每个用户。

要创建您要执行的地图:

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

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

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

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

// 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));

将您的文件读入 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()));

免责声明:在 phone 上翻阅的代码 - 可能包含语法错误

Google Guava Multimap is the exact structure for this. A Multimap<K, V> 在概念上与 Map<K, Collection<V>> 相同,这就是您想要的。

特别是,ListMultimap 最适合您的情况。您可以混合使用 Guava 和 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() and Multimaps.transformValues() 文档以获取更多参考。