【问题标题】:Java - Reorder Map<String, List<String>>Java - 重新排序 Map<String, List<String>>
【发布时间】:2015-02-14 08:09:17
【问题描述】:

我有一个名为 data 的 Map> 看起来像这样

data = {Salad=[Salad Bar Station, Green Pepper & Tomato Salad, Lo Mein Noodle Salad], 
        Pizza=[Cheese Pizza - Slice, Pepperoni Pizza, Tomato Bruschetta Flatbread Pizza, Herb 
               Seasoned Breadsticks, Spaghetti Sauce with Tomato Bits], 
        Dessert=[Carnival Cookies, Sweet Cinnamon Brownies, Oreo Crumble Pudding Cup, 
                 Cherry Jell-O Parfait], 
        Cold Cereal=[Miscellaneous/Peripherals]}

现在我想重新排序,让它看起来像这样

data = Pizza=[Cheese Pizza - Slice, Pepperoni Pizza, Tomato Bruschetta Flatbread Pizza, Herb 
               Seasoned Breadsticks, Spaghetti Sauce with Tomato Bits], 
       Salad=[Salad Bar Station, Green Pepper & Tomato Salad, Lo Mein Noodle Salad],
       Cold Cereal=[Miscellaneous/Peripherals]
       Dessert=[Carnival Cookies, Sweet Cinnamon Brownies, Oreo Crumble Pudding Cup, 
                 Cherry Jell-O Parfait]}

现在我有一些关于如何执行此操作的伪代码,只是不太确定如何在代码中执行此操作。

所以我想要一个按我想要的键顺序排列的数组。所以它会像

String[] desiredOrder = {"Pizza","Salad","Cold Cereal"};
int destination = 0;

然后有类似的东西

for (int i=0; i < desiredOrder.length; i++) {
     //then find if the first desiredOrder object is in the data array
         //then check if it is in the right spot
             if (it is in right spot) {
                 //do nothing
             }
             else {
                  //move it to the right spot
             }
 }

非常感谢您能帮我填写其余部分,以便将键及其值移动到正确的位置。

提前感谢您的帮助。

编辑

为了做到这一点,我正在从网络上解析 xml,这就是我正在做的事情,请注意我刚刚将其更改为 LinkedHashMap,所以现在它按 xml 的顺序获取它,但我仍然想重新排列它我自己的订单。

String currentDay = "";
String currentMeal = "";
String counter = "";

 LinkedHashMap<String, List<String>> itemsByCounter = new LinkedHashMap<String , List<String>>();
        List<String> items = new ArrayList<String>();
while (eventType != XmlResourceParser.END_DOCUMENT) {
            String tagName = xmlData.getName();
            blogPost = new HashMap<String, String>();

            switch (eventType) {
                case XmlResourceParser.START_TAG:
                    if (tagName.equalsIgnoreCase("day")) {
                        currentDay = xmlData.getAttributeValue(null, "name");
                    }
                    if (tagName.equalsIgnoreCase("meal")) {
                        currentMeal = xmlData.getAttributeValue(null, "name");
                    }
                    if (tagName.equalsIgnoreCase("counter") && currentDay.equalsIgnoreCase(day) && currentMeal.equalsIgnoreCase(meal)) {
                        counter = xmlData.getAttributeValue(null, "name");
                    }

                    break;
                case XmlResourceParser.TEXT:
                    if (currentDay.equalsIgnoreCase(day) && currentMeal.equalsIgnoreCase(meal)) {
                        if (xmlData.getText().trim().length() > 0) {
                            items.add(xmlData.getText());

                        }

                    }
                    break;

                case XmlPullParser.END_TAG:
                    if (tagName.equalsIgnoreCase("counter")) {
                        if (items.size() > 0) {
                            itemsByCounter.put(counter, items);
                            items = new ArrayList<String>();
                        }
                    }
                    break;
            }
            eventType = xmlData.next();
        }

对不起,它很长,但基本上它只是抓取项目,添加一个作为键,然后将其下的作为值。

这是我用数据填充 ListView 的方法。

MyCustomAdapter mAdapter = new MyCustomAdapter();
    for (int i = 0; i < data.size(); i++) {
        Object[] array = data.keySet().toArray();
        String string = array[i].toString();
        mAdapter.addSeparatorItem(string);
        for (int i2 = 0; i2 < data.get(string).size(); i2++) {
            mAdapter.addItem(data.get(string).get(i2));
        }

    }
public class MyCustomAdapter extends BaseAdapter{
    ArrayList mData = new ArrayList();
    LayoutInflater mLayoutInflater;

    private static final int TYPE_ITEM = 0;
    private static final int TYPE_SEPARATOR = 1;
    private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;

    private TreeSet mSeparatorsSet = new TreeSet();

    public MyCustomAdapter() {
        mLayoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public void addItem(final String item) {
        mData.add(item);
        notifyDataSetChanged();
    }

    public void addSeparatorItem(final String item) {
        mData.add(item);
        // save separator position
        mSeparatorsSet.add(mData.size() - 1);
        notifyDataSetChanged();
    }

    @Override
    public int getItemViewType(int position) {
        return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
    }

    @Override
    public int getViewTypeCount() {
        return TYPE_MAX_COUNT;
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public String getItem(int position) {
        return mData.get(position).toString();
    }

    @Override
    public long getItemId(int position) {
        return position;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder = null;
        int type = getItemViewType(position);
        System.out.println("getView " + position + " " + convertView + " type = " + type);
        if (convertView == null) {
            holder = new ViewHolder();
            switch (type) {
                case TYPE_ITEM:
                    convertView = mLayoutInflater.inflate(R.layout.item_cell_view, parent, false);
                    holder.textView = (TextView)convertView.findViewById(R.id.text);
                    break;
                case TYPE_SEPARATOR:
                    Context context = DiningItemsActivity.this;
                    convertView = mLayoutInflater.inflate(R.layout.header_cell_view, parent, false);
                    holder.textView = (TextView)convertView.findViewById(R.id.textSeparator);
                    convertView.setBackgroundColor(colorBar);
                    break;
            }
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }
        holder.textView.setText(mData.get(position).toString());
        return convertView;
    }

    public class ViewHolder {
        public TextView textView;
    }

【问题讨论】:

  • 为什么要这样做?重点是什么? Maps 通常没有特定的顺序(例如 HashMap 是按键的哈希排序的......)
  • @MichelMichaelMeyer 我正在使用此数据并将其显示在列表视图中,并且我希望更重要的数据位于顶部,我将键用作部分标题以及其中的值和数据部分
  • @iqueqiorio 看看答案,对你有帮助吗,使用linkedHashMap
  • 你不能只遍历desiredOrder,使用它的Strings作为Keys,然后将它们依次传递到列表视图中吗?
  • @MichelMichaelMeyer 你介意张贴你的意思吗,这很难分辨

标签: java android arrays sorting hashmap


【解决方案1】:

我认为使用 linkedHashMap 应该可以解决您的问题。要么在开始时使用linkedHashMap,要么它会保持顺序,或者从你的另一张地图和iterate填充它。

填写myMap的伪代码

public static void main(String[] args) throws Exception {

        LinkedHashMap<String, List<String>> linkedHashMap = new LinkedHashMap<String, List<String>>();
        String[] desiredOrder = { "Pizza", "Salad", "Cold Cereal", "Dessert" };

        Map<String, List<String>> myMap = new HashMap<String, List<String>>();

        List<String> myList1 = new ArrayList<String>();
        List<String> myList2 = new ArrayList<String>();
        List<String> myList3 = new ArrayList<String>();
        List<String> myList4 = new ArrayList<String>();

        myList1.add("Salad Bar Station, Green Pepper & Tomato Salad");
        myList1.add("Lo Mein Noodle Salad");
        myMap.put("Salad", myList1);

        myList2.add("Cheese Pizza - Slice");
        myList2.add("Pepperoni Pizza");
        myList2.add("Tomato Bruschetta Flatbread Pizza");
        myList2.add("HerbSeasoned Breadsticks");
        myList2.add("Spaghetti Sauce with Tomato Bits");
        myMap.put("Pizza", myList2);

        myList3.add("Carnival Cookies");
        myList3.add("Sweet Cinnamon Brownies");
        myList3.add("Oreo Crumble Pudding Cup");
        myList3.add("Cherry Jell-O Parfait");
        myMap.put("Dessert", myList3);

        myList4.add("Miscellaneous/Peripherals");
        myMap.put("Cold Cereal", myList4);

        System.out.println(myMap);

        for (int i = 0 ; i < desiredOrder.length ; i++) {
            linkedHashMap.put(desiredOrder[i], myMap.get(desiredOrder[i]));
        }

        System.out.println("-------------------------------");
        System.out.println(linkedHashMap);
    }

输出

{沙拉=[沙拉吧台,青椒番茄沙拉,捞面 沙拉],甜点=[嘉年华饼干,甜肉桂布朗尼,奥利奥 碎布丁杯,樱桃果冻冻糕],冷 Cereal=[Miscellaneous/Peripherals], Pizza=[Cheese Pizza - Slice, 意大利辣香肠披萨、番茄意式烤面包披萨、香草调味 面包棒,番茄片意大利面酱]}


{Pizza=[芝士比萨 - 切片、意大利辣香肠比萨、番茄意式烤面包 大饼披萨、香草调味面包条、番茄意大利面酱 位],沙拉=[沙拉吧站,青椒番茄沙拉,捞面 面条沙拉],冷麦片=[杂项/外围设备], 甜点=[嘉年华饼干、甜肉桂布朗尼、奥利奥碎 布丁杯,樱桃果冻冻糕]}

【讨论】:

  • 我试过了,其中一些值变成了 null,它删除了原始数据中的其他键,如果还有其他键,我只想让它们保持不变
  • 对,好吧,我得到了相同的输出,但我不想删除甜点,有没有办法在不将它放在所需的 order 数组中的情况下解决这个问题
【解决方案2】:
public class TestComparator implements Comparator<String> {
    List<String> order;
    public TestComparator(String[] desiredOrder) {
        order = Arrays.asList(desiredOrder);
    }

    public static void main(String args[]) throws InterruptedException {
        String[] desiredOrder = {"Pizza","Salad","Cold Cereal"};
        TreeMap<String, List<String>> treeMap = new TreeMap<String, List<String>>(new TestComparator(desiredOrder));

        //add into Map
    }
    @Override
    public int compare(String o1, String o2) {
        Integer index1 =order.indexOf(o1);
        Integer index2 =order.indexOf(o2);
        return index1.compareTo(index2);
    }
}

【讨论】:

  • 这会删除其他键和值吗?还是会保留 TreeMap 的末尾?
  • 根据TestComparator插入新元素后会重新排序
  • 对不起,我不熟悉这个类和实现,编译错误Class 'Test Compare' must either be declared abstract or implement abstract method Compare(T,T)
  • 现在我已经纠正了一些显示问题。请复制粘贴
  • 好的,所以现在叫它我有这个。 TestComparator testComparator = new TestComparator(desiredOrder); 然后呢?
猜你喜欢
  • 2016-11-25
  • 2020-01-26
  • 2020-03-17
  • 1970-01-01
  • 2021-04-25
  • 1970-01-01
  • 1970-01-01
  • 2018-08-02
  • 2018-09-06
相关资源
最近更新 更多