从 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()
文档以获取更多参考。
我有一个如下所示的文件:
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()
文档以获取更多参考。