【问题标题】:Sorting a Array based on another array根据另一个数组对数组进行排序
【发布时间】:2014-05-05 10:23:26
【问题描述】:

我有 2 个数组:

第一个由人名组成。第二个给了我一个页面中出现的名字的数量。 例如:Names=["James","Loiui","Mario","Peter"] 计数=[1,4,2,5]

现在我尝试使用以下代码:

SortedMap<Integer, String> m = new TreeMap<Integer, String>();
for(int i = 0; i < Names.size(); i++)
        m.put( count.get(i),Names.get(i));

但这不起作用,因为 count 有重复值。我发现问题出在 TreeMap 上,因为它只存储唯一元素。现在要克服我的问题,还有其他有效的解决方案吗?

【问题讨论】:

  • 名称可能是唯一的,因此您应该使用SortedMap&lt;String, Integer&gt;。但是,如果您的目标是按计数排序,请使用 SortedMap&lt;Integer, List&lt;String&gt;&gt;
  • 但我希望最终结果根据 count 降序排列,即首先出现的重复次数最多的名称
  • 那么你可以使用SortedMap&lt;Integer, List&lt;String&gt;&gt;,就像我说的那样。
  • 那么我不能有 2 个计数值相同!
  • 为什么?如果您有两个相同的计数值,您将拥有从该值到 2 个名称的列表的映射。

标签: java arrays treemap sortedmap


【解决方案1】:

创建一个类PersonFrequency,包含一个名称和一个计数。创建一个 单个 数组或 PersonFrequency 实例列表。按计数对该数组进行排序:

Java 8 示例:

List<PersonFrequency> list = new ArrayList<>(names.length);
for (int i = 0; i < names.length; i++) {
    list.add(new PersonFrequency(names[i], counts[i]);
}

list.sort(Comparator.comparing(PersonFrequency::getCount).reversed());

List<String> sortedNames = list.stream()
                               .map(PersonFrequency::getName)
                               .collect(Collectors.toList());

在 Java 7 中,排序会变成

Collections.sort(list, new Comparator<PersonFrequency>() {
    @Override
    public int compare(PersonFrequency p1, PersonFrequency p2) {
        return Integer.compare(p2.getCount(), p1.getCount());
    }
});

【讨论】:

  • 能否详细说明。
  • 详细说明什么?示例代码还不够好理解吗?
  • 有什么方法可以在 java 1.7 中使用 PersonFrequency List 吗?
  • 当然。您只需要使用 Collections.sort() 并使用匿名类而不是 lambda 定义 Comparator。必须有数百个问题询问如何在 Java 中对对象列表进行排序。为他们谷歌,或阅读我编辑的答案。
【解决方案2】:

按字母排序

    String [] names = {"Aaa","Bbb"};
    int [] count = {1,2};

    SortedMap<String, Integer> m = new TreeMap<String, Integer>();

    for(int i = 0; i < names.length; i++){
        m.put(names[i], count[i]);
    }

按编号排序:

    String [] names = {"Aaa","Bbb"};
    int [] count = {2,1};

    SortedMap<Integer, String> m = new TreeMap<Integer, String>();

    for(int i = 0; i < names.length; i++){
        m.put(count[i],names[i]);
    }

对于降序将您的排序地图更改为此

SortedMap<Integer, String> m = new TreeMap<Integer, String>().descendingMap();

【讨论】:

  • 同意!但我希望根据计数值的数量对结果结果进行排序。而不是按字母顺序!
【解决方案3】:

如前面的 cmets 中所述,您可以拥有一个带有 Integer 和 ArrayList 参数的排序映射,如下所示,

SortedMap<Integer, ArrayList<String>> map=new TreeMap<Integer, ArrayList<String>>().descendingMap();

由于您希望结果按降序排列,我添加了descendingMap()。

我们使用 ArrayList 是因为您可能在 count 数组中有重复项。多个名称可以具有相同的计数值。所以一个计数将有一个名称列表。

完整的代码如下,

import java.util.ArrayList;
import java.util.SortedMap;
import java.util.TreeMap;



public class NameCount {

    public static void main(String[] args) {

        String[] names = {"James","Loiui","Mario","Peter"};
        int[] count = {1, 4, 2, 1};

        SortedMap<Integer, ArrayList<String>> map=new TreeMap<Integer, ArrayList<String>>().descendingMap();
        ArrayList<String> nameList=null;

        for(int i = 0; i < names.length; i++)
        {
            if(map.get(count[i])==null)
            {
                nameList = new ArrayList<String>();
                nameList.add(names[i]);
                map.put(count[i], nameList);
            }
            else
            {
                map.get(count[i]).add(names[i]);
            }
        }

        for(int countVal : map.keySet())
        {
            ArrayList<String> namesListVal=map.get(countVal);

            System.out.print("\nCount  "+countVal+ ":  NAMES  : ");
            for(String name : namesListVal)
            {
                System.out.print(name+"  ");
            }

        }
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 1970-01-01
    • 2013-11-10
    • 2021-11-20
    • 2016-06-02
    相关资源
    最近更新 更多