在Java中迭代映射

在Java中迭代映射,java,arraylist,collections,maps,treemap,Java,Arraylist,Collections,Maps,Treemap,以下问题: 我得到了一个树形图,其中字符串作为键,集合以ArrayList的形式作为值。 在字符串中,我保存了一家汽车租赁公司的客户姓名,在数组列表中,我得到了他们曾经租用过的所有汽车名称。 例如: 史密斯:[奥迪、宝马、马自达] 米勒:[奥迪、法拉利、大众] 现在我构建了第二个树形图,其中字符串作为键,整数作为值。 字符串应为公司的所有汽车名称,整数为租赁次数 如何轻松地遍历第一个地图以节省第二个地图中的租车数量? 第一张地图中的ArrayList给我带来了麻烦 谢谢你的帮助 在这一部分中,我

以下问题:

我得到了一个树形图,其中字符串作为键,集合以ArrayList的形式作为值。 在字符串中,我保存了一家汽车租赁公司的客户姓名,在数组列表中,我得到了他们曾经租用过的所有汽车名称。 例如:

史密斯:[奥迪、宝马、马自达] 米勒:[奥迪、法拉利、大众]

现在我构建了第二个树形图,其中字符串作为键,整数作为值。
字符串应为公司的所有汽车名称,整数为租赁次数

如何轻松地遍历第一个地图以节省第二个地图中的租车数量? 第一张地图中的ArrayList给我带来了麻烦

谢谢你的帮助

在这一部分中,我将数据放入第二张地图中。course是第一张地图的名称,numberOfCars是第二张地图的名称

        int helpNumber = 0;
        for (Iterator<String> it = course.keySet().iterator(); it.hasNext(); ){
            Object key = it.next();
            if(course.get(key).contains(chooseName)){
                helpNumber++;
            }
            System.out.println((course.get(key).contains(chooseName)));
        }
        if(helpNumber == 1) {
            numberOfCars.put(chooseName, 1);
        } else if(helpNumber > 1) {
            int increasing = numberOfCars.get(chooseName);
            increasing++;
            numberOfCars.put(chooseName, increasing);
        }
在下面的部分中,我尝试以这种方式打印它:

宝马:3 大众:2 奥迪:0 马自达:0

因此,相同租赁金额的组放在一起,组内的汽车名称按字母顺序排序

    System.out.println("+++++++ car popularity +++++++");
    Object helpKey = null;
    for(Iterator<String> it = numberOfCars.keySet().iterator(); it.hasNext();) {
        Object key = it.next();
        if (helpKey == null){
            helpKey = key;
        }
        if(numberOfCars.get(key) > numberOfCars.get(helpKey)) {
            helpKey = key;
        }
    }
    int maxCount = numberOfCars.get(helpKey);
    for(int i = maxCount; i >= 0; i--) {
        for(Iterator<String> it = numberOfCars.keySet().iterator(); it.hasNext();) {
            Object key = it.next();
            if(numberOfCars.get(key) == maxCount) {
                System.out.println((String) key + ": " + numberOfCars.get(key));
            }
        }
    }
[我还不能评论]由于您命名变量的方式,您提供的代码非常混乱。不要将变量命名为SomeType helpXxx来表示您需要此变量的帮助,如果您的代码显示正确,人们将很容易区分哪些变量给您带来了麻烦以及原因

您收到的评论正确地指出,您需要根据您遇到的具体问题提出问题,而不是帮助我获得此值。您的具体问题是,当值的类型为Collection时,遍历映射中包含的值

这就是说,由于我需要销售代表来逃离新用户堆栈交换牢狱,以下是您的解决方案:

这将编译并运行,无需任何更改或额外导入

进一步资料 这看起来像是您过度思考了如何获得所需的结果,或者您没有很好地掌握Map类,因此只是在摸索。我们都这么做。。。12小时后,我们都恨自己这么做。仔细想想:

确定主要问题:遍历第一个映射中包含的所有值。 在掌握问题之前,不要忙于实施细节,又名:

映射中值V的类型,在本例中为ArrayList 使用什么类型的地图 代码中的不返回点是当您尝试在第一个地图的值中计算汽车品牌的出现次数并将这些计数存储到第二个地图中时。下面是一个带有代码提示的菜谱,可以帮助您处理它

从CustomerEntals映射1获取所有值 集合eachCustomersRentals=CustomerRentals.values; 迭代每个客户的租金,存储每个客户的总计数 汽车品牌 对于Arraylist AcustomerRentals:each客户关系{…} 在{…}中,首先为遍历的每个循环嵌套一个增强的 针茅属 然后在嵌套循环中计算特定客户的品牌 租用,将各个计数存储在范围内的变量中 对于每个构造,方法aka在外部 初始化第二个映射 将每个汽车品牌及其数量放入第二张地图
如果您不知道如何实现自定义比较器来为您提取细节,那么您想要为输出实现的排序将非常混乱。如果您必须进行此排序,请仔细查看Comparator和Comparable接口文档Google Comparator/Comparable,然后分析我是如何实现它的。

它是如何给您带来问题的?你能包括你的代码并解释你哪里出错吗?Stackoverflow不是来帮你做这项工作的。你至少要自己试试,如果你的代码有问题,我们很乐意帮助你。字符串应该是公司所有的汽车名称。。。我在你的设计中看不到任何公司的参考资料,你如何确定哪辆车是哪辆车?例如,该公司只有一辆宝马、一辆大众等。该计划并不复杂。我在上面发布了我的代码。我找不到任何关于这个答案的单词!我仍然在学习你的代码,但我已经学到了很多!正如您正确猜测的那样,我一般不熟悉地图和Java。您将整个代码拆分为不同类的方法使问题变得更容易。在我的完整版本中,一个类中有300行代码,没有注释就无法理解任何内容。你真的帮了我很多,让我开心!谢谢你我很高兴能帮上忙!请随时要求澄清:Java集合框架可能很难让您理解,而且从一开始就非常难以理解,我几个月前还处于您的位置
import java.util.*;

public class Test {
  public static void main(String[] args) {
    String[] customers = {
      "Mr PoopyButtHole", "Stealy", "Bird Person"
    };

    CarBrand audi = new CarBrand("Audi");
    CarBrand bmw = new CarBrand("BMW");
    CarBrand mazda = new CarBrand("Mazda");
    CarBrand vw = new CarBrand("VW");
    CarBrand ferrari = new CarBrand("Ferrari");

    // First Map: Customers paired with car brands they've rented
    SortedMap<String, List<CarBrand>> customerRentals =
      new TreeMap<String, List<CarBrand>>();
    // --- Fill the first map with info ---
    // For customer Mr PoopyButtHole
    List<CarBrand> mrPBHRentals = new ArrayList<>();
    Collections.addAll(mrPBHRentals, audi, bmw, mazda);
    customerRentals.put(customers[0], mrPBHRentals);
    // For customer Stealy
    List<CarBrand> stealyRentals = new ArrayList<>();
    Collections.addAll(stealyRentals, bmw, mazda, vw);
    customerRentals.put(customers[1], stealyRentals);
    // For customer Bird Person
    List<CarBrand> birdPersonRentals = new ArrayList<>();
    Collections.addAll(birdPersonRentals, audi, bmw, mazda, ferrari);
    customerRentals.put(customers[2], birdPersonRentals);

    // First Map contains 10 occurences of car brands across all the individual
    // arraylists paired to a respective customer

    // Second Map: Car brands paired with the amount of times they've been
    // rented
    // You don't actually need the second map to be a TreeMap as you want to
    // rearrange the results into your desired format at the end anyway
    Map<CarBrand, Integer> carBrandRentalCounts = new HashMap<>();
    // Place each CarBrand into carBrandRentalCounts and initialize the counts
    // to zero
    carBrandRentalCounts.put(audi, 0);
    carBrandRentalCounts.put(bmw, 0);
    carBrandRentalCounts.put(mazda, 0);
    carBrandRentalCounts.put(vw, 0);
    carBrandRentalCounts.put(ferrari, 0);

    // Get all the values (each ArrayList of carbrands paired to a customer) in
    // the first map
    Collection<List<CarBrand>> values = customerRentals.values();

    // Iterate through 'values' (each ArrayList of car brands rented)
    int total = 0;
    for(List<CarBrand> aCustomersRentals : values)
      for(CarBrand brand : aCustomersRentals) {
        // Get the current count for 'brand' in the second map
        Integer brandCurrentCount = carBrandRentalCounts.get(brand);
        // Increment the count for 'brand' in the second map
        Integer newBrandCount = brandCurrentCount+1;
        carBrandRentalCounts.put(brand, newBrandCount);

        total++;
      }

    // Init. a List with the entries
    Set<Map.Entry<CarBrand,Integer>> entries = carBrandRentalCounts.entrySet();
    List<Map.Entry<CarBrand,Integer>> listOfEntries =
      new ArrayList<Map.Entry<CarBrand,Integer>>(entries);
    // Sort the entries with the following priority:
    // 1st Priority: Highest count
    // 2nd Priority: Alphabetical order
    // NOTE: CustomSortingComparator implements this priority
    Collections.sort(listOfEntries, new CustomSortingComparator());

    // Print the results
    System.out.println("Count of rentals for each car brand:");
    for(Map.Entry<CarBrand, Integer> entry : listOfEntries)
      System.out.println("  " + entry.getKey() + " --> " + entry.getValue());
    System.out.println("Total:" + total);

    // Verify that our custom sorted entries are indeed being sorted correctly
    // Change the counts to be all the same
    for(Map.Entry<CarBrand, Integer> entry : entries)
      entry.setValue(10);
    // Resort the entries
    Collections.sort(listOfEntries, new CustomSortingComparator());
    // Print with the test entries
    System.out.println();
    System.out.println("With test entries where all counts are the same:");
    for(Map.Entry<CarBrand, Integer> entry : listOfEntries)
      System.out.println("  " + entry.getKey() + " --> " + entry.getValue());
    System.out.println("Total:" + total);
    // Change the counts so that the ordering is the alphabetically highest
    // brands followed by the lowest
    for(int i = listOfEntries.size()-1; i >= 0; i--)
      listOfEntries.get(i).setValue(i);
    // Resort the entries
    Collections.sort(listOfEntries, new CustomSortingComparator());
    // Print with the test entries
    System.out.println();
    System.out.println("with test entries where the \"bigger\" car brands " +
      "alphabetically have higher counts:");
    for(Map.Entry<CarBrand, Integer> entry : listOfEntries)
      System.out.println("  " + entry.getKey() + " --> " + entry.getValue());
    System.out.println("Total:" + total);
  }
}

class CustomSortingComparator
implements Comparator<Map.Entry<CarBrand,Integer>> {
  public int compare(Map.Entry<CarBrand, Integer> entry1,
                     Map.Entry<CarBrand, Integer> entry2) {
    CarBrand brand1 = entry1.getKey();
    CarBrand brand2 = entry2.getKey();
    int brandResult = brand1.compareTo(brand2);
    Integer count1 = entry1.getValue();
    Integer count2 = entry2.getValue();
    int countResult = count1.compareTo(count2);

    return
      countResult > 0 ?
        -1 : countResult < 0 ?
          1 : brandResult < 0 ?  // <-- equal counts here
            -1 : brandResult > 1 ?
              1 : 0;
  }
}

// DONT WORRY ABOUT THIS CLASS, JUST MAKES IT EASIER TO IDENTIFY WHAT'S GOING
// ON IN THE FIRST MAP
class CarBrand implements Comparable<CarBrand> {
  public final String brand;

  public CarBrand(String brand) { this.brand = brand; }

  @Override
  public int compareTo(CarBrand carBrand) {
    return brand.compareTo(carBrand.brand);
  }

  @Override
  public boolean equals(Object o) {
    // IF o references this CarBrand instance
    if(o == this) return true;
    // ELSE IF o is of type CarBrand, perform equality check on field 'brand'
    else if(o instanceof CarBrand) {
      CarBrand obj = (CarBrand)o;
      // IF the brands are equal, o is equal to this CarBrand
      if(brand.equals(obj.brand)) return true;
    }

    return false;
  }

  @Override
  public String toString() { return brand; }

  @Override
  public int hashCode() { return brand.hashCode(); }
}
Count of rentals for each car brand:
  BMW --> 3
  Mazda --> 3
  Audi --> 2
  Ferrari --> 1
  VW --> 1
Total:10

With test entries where all counts are the same:
  Audi --> 10
  BMW --> 10
  Ferrari --> 10
  Mazda --> 10
  VW --> 10
Total:10

with test entries where the "bigger" car brands alphabetically have higher counts:
  VW --> 4
  Mazda --> 3
  Ferrari --> 2
  BMW --> 1
  Audi --> 0
Total:10