我正在尝试编写一个程序,该程序从输入文件读取并按其十六进制值对颜色进行配对。例如:黑色000000将是一对。以下是我到目前为止的情况:
public class HexColors{
public static void main(String[] args) throws IOException {
ArrayList <String> colorsArray = new ArrayList<String>();
Scanner hexColors = new Scanner(new File("input.txt"));
while (hexColors.hasNext()) {
colorsArray.add(hexColors.nextLine());
}
// Assuming I have to use a map to accomplish this.
Map<String, String> hexMap = new HashMap<String, String>();
System.out.println("Test" + hexMap);
System.out.print("The colors entered were:\n" );
for (Iterator<String> itr = colorsArray.iterator(); itr.hasNext();)
System.out.print(itr.next() + "\n");
Collections.sort(colorsArray);
System.out.println("The colors sorted by name are:");
for(String colorsSorted : colorsArray){
System.out.println(colorsSorted);
}
}
}
现在我按照颜色的自然顺序显示它,通过使用collections.sort,我也按字母顺序显示它们。重要提示:我不是在寻找一个完整的解决方案,只是关于我接下来应该去哪里的一些指示。是否可以将input.txt中的输入存储为Map?或者我应该以某种方式将ArrayList转换为地图?谢谢你的帮助。
答案 0 :(得分:1)
如果您的输入文件每行包含一个颜色对,则更容易逐行读取文件BufferedReader
(请参阅BufferedReader.readLine())然后拆分每行以提取颜色名称和十六进制值。
Reader reader = new BufferedReader(new FileReader("input.txt"));
String line;
while((line = reader.readLine()) != null) {
// Split line
// Add color name and hex value to your data structure
}
分割这样一条线有很多种方法。例如。你可以使用String.split()。 或者,您可以通过String.indexOf()搜索空格字符位置,然后使用String.substring()提取部分。
对于您的数据模型,也有很多替代方案。 HashMap
可能是一个好主意,因为您始终拥有映射到十六进制值的颜色名称。您确定每个颜色名称在您的文件中是唯一的吗?
但仅使用HashMap
您将丢失原始订单。更合适的数据结构是LinkedHashMap
,它在内部使用双向链表来保存插入顺序。
因此,使用LinkedHashMap
,您已完成第一个用例(原始订单)。迭代LinkedHashMap
,你就完成了。
迭代Map
的最佳方法是使用entrySet():
for(Entry<String, String> colorPair : map.entrySet()) {
String colorName = colorPair.getKey();
String colorHex = colorPair.getValue();
// Process colorName and colorHex ...
}
对于字母顺序,您可以获取地图keySet()的所有条目,并将其放入ArrayList
并使用Collections.sort()
。然后迭代ArrayList
并通过地图检索十六进制值。听起来有点复杂。但这是可行的。
但困难的部分是自然颜色顺序(你的意思是按十六进制值排序,对吧?)。因此,您可以通过Map.values()获取所有颜色十六进制值,对它们进行排序......
你不能反过来使用地图。在这里,您希望通过十六进制值检索颜色名称,但颜色名称是地图的键。我假设您不想使用第三方库,并且Java的标准库中没有双向映射。
当然你可以使用第二张还原地图,但也许我们应该在开始时重新考虑使用地图作为数据模型的选择。
更简单的方法是创建自己的ColorPair
类,然后使用简单的ArrayList
来保存所有颜色对。插入所有颜色对后,列表具有原始顺序。然后,您可以使用Collections.sort()
按颜色名称排序,然后按颜色十六进制值。
这将是一个简单的ColorPair
实现:
class ColorPair {
private String name;
private String hex;
public ColorPair(String name, String hex) {
this.name = name;
this.hex = hex;
}
public String getName() {
return name;
}
public String getHex() {
return hex;
}
@Override
public String toString() {
return String.format("[ColorPair name=%s, hex=%s]", name, hex);
}
}
您可以在此处实施Comparable界面,并为ColorPair
个实例定义默认订单。但是你想要两个不同的命令,所以你必须使用Comparator类来Collections.sort()
。 (您可以尝试将其作为练习。)
假设您有一个方法parseColorPair()
,它接受一行输入文件并返回一个ColorPair
实例,您可以这样读取您的文件:
Reader reader = new BufferedReader(new FileReader("input.txt"));
String line;
List<ColorPair> colorPairs = new ArrayList<ColorPair>();
while((line = reader.readLine()) != null) {
colorPairs.add(parseColorPair(line));
}
// Output in original order
for(ColorPair colorPair: colorPairs) {
System.out.println(colorPair); // using our custom ColorPair.toString() method
}
要按颜色名称对列表进行排序,您必须实现界面Comparator<ColorPair>
。
Collections.sort(colorPairs, new Comparator<ColorPair>() {
public int compare(ColorPair colorPair1, ColorPair colorPair2) {
// Compare the names of colorPair1 and colorPair2 and return
// a negative value, if colorPair1.getName() is lesser than colorPair2's name.
// return a positive value (greater than 0) if the first name is greater than
// the second name and return 0 if the names are equal.
// Hint: Look for String.compare()
}
});
如果没有Collections.sort()
,则无法使用Comparator
版本,因为您的ColorPair
类未实现Comparable<ColorPair>
接口。
按十六进制值排序是类似的。 Comparator
实现的不同之处仅在于比较十六进制值而不是名称。
因此,使用正确的数据结构可以直接实现用例,但为给定问题找到正确的数据结构并非易事。