【问题标题】:Need to use collections to sort colors by name and be hex value需要使用集合按名称对颜色进行排序并为十六进制值
【发布时间】:2014-03-31 04:24:25
【问题描述】:

我正在尝试编写一个程序,该程序从输入文件中读取并按十六进制值对颜色进行配对。例如:黑色 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 中的输入存储为地图?或者我应该以某种方式将 ArrayList 转换为地图?感谢您的帮助。

【问题讨论】:

  • 您能提供几行 input.txt 以便我们查看它的格式吗?
  • @PaulStatham 这里有两种颜色:紫色 990099 橙色 FF6600
  • 是每行一个颜色对还是一行可以包含多对?
  • @vanje 每行一个颜色对。

标签: java collections arraylist map hashmap


【解决方案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&lt;ColorPair&gt;

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()
  }
});

你不能在这里使用没有ComparatorCollections.sort() 版本,因为你的ColorPair 类没有实现Comparable&lt;ColorPair&gt; 接口。

按十六进制值排序类似。 Comparator 实现的不同之处仅在于比较十六进制值而不是名称。

因此,使用正确的数据结构可以直接实现用例,但为给定问题找到正确的数据结构并非易事。

【讨论】:

  • 非常感谢您!解释得比我想象的要好。
猜你喜欢
  • 2016-09-25
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 2019-07-09
  • 2016-05-11
  • 2012-07-29
  • 2011-07-31
  • 1970-01-01
相关资源
最近更新 更多