Apache Commons Collections OrderedMap – 阿帕奇公社集合有序地图

最后修改: 2017年 6月 28日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

The Apache Commons Collections library provides useful classes that complement the Java Collections Framework.

Apache Commons集合库提供了补充Java集合框架的有用类。

In this article, we will review the interface OrderedMap, which extends java.util.Map.

在这篇文章中,我们将回顾OrderedMap接口,它扩展了java.util.Map

2. Maven Dependency

2.Maven的依赖性

The first thing we need to do is to add the Maven dependency in our pom.xml :

我们需要做的第一件事是在pom.xml中添加Maven依赖。

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.1</version>
</dependency>

You can find the latest version of the library on the Maven Central repository.

您可以在Maven Central资源库上找到该库的最新版本。

3. OrderedMap Properties

3.OrderedMap属性

Simply put, a map that implements the OrderedMap interface:

简单地说,就是一个实现了OrderedMap接口的地图。

  • Maintains order in its set of keys, although the set isn’t sorted
  • Can be iterated over in both directions with methods: firstKey() and nextKey(), or lastKey() and previousKey()
  • Can be traversed with a MapIterator (also provided by the library)
  • Provides methods to find, alter, remove, or replace elements

4. Using OrderedMap

4.使用OrderedMap

Let’s set up an OrderedMap of runners and their ages in a test class. We will use a LinkedMap – one of the OrderedMap implementations provided in the library.

让我们在一个测试类中设置一个跑步者及其年龄的OrderedMap。我们将使用一个LinkedMap–库中提供的OrderedMap的实现之一。

First, let’s set up arrays of runners and ages that we will use to load the map and verify the order of the values:

首先,让我们设置跑步者和年龄的数组,我们将使用这些数组来加载地图并验证数值的顺序。

public class OrderMapUnitTest {
    private String[] names = {"Emily", "Mathew", "Rose", "John", "Anna"};
    private Integer[] ages = {37, 28, 40, 36, 21};
    private LinkedMap<String, Integer> runnersLinkedMap;
 
    //...
}

Now, let’s initialize our map:

现在,让我们来初始化我们的地图。

@Before
public void createRunners() {
    this.runnersLinkedMap = new LinkedMap<>();
    
    for (int i = 0; i < RUNNERS_COUNT; i++) {
        runners.put(this.names[i], this.ages[i]);
    }
}

4.1. Forward Iteration

4.1.正向迭代

Let’s see how the forward iterator is used:

让我们看看正向迭代器是如何使用的。

@Test
public void givenALinkedMap_whenIteratedForwards_thenPreservesOrder() {
    String name = this.runnersLinkedMap.firstKey();
    int i = 0;
    while (name != null) {
        assertEquals(name, names[i]);
        name = this.runnersLinkedMap.nextKey(name);
        i++;
    }
}

Note that when we have reached the last key, the method nextKey() will return a null value.

注意,当我们到达最后一个键时,方法nextKey()将返回一个null

4.2. Backward Iteration

4.2.后向迭代

Now let’s iterate back, starting with the last key:

现在让我们回溯一下,从最后一个键开始。

@Test
public void givenALinkedMap_whenIteratedBackwards_thenPreservesOrder() {
    String name = this.runnersLinkedMap.lastKey();
    int i = RUNNERS_COUNT - 1;
    while (name != null) {
        assertEquals(name, this.names[i]);
        name = this.runnersLinkedMap.previousKey(name);
        i--;
    }
}

Once we reach the first key, the previousKey() method will return null.

一旦我们到达第一个键,previousKey()方法将返回null.

4.3. MapIterator Example

4.3.MapIterator 示例

Now let’s use the mapIterator() method to obtain a MapIterator as we show how it preserves the order of runners as defined in the arrays names and ages:

现在让我们使用mapIterator()方法来获得一个MapIterator,因为我们展示了它是如何保留数组namesages中定义的跑步者的顺序。

@Test
public void givenALinkedMap_whenIteratedWithMapIterator_thenPreservesOrder() {
    OrderedMapIterator<String, Integer> runnersIterator 
      = this.runnersLinkedMap.mapIterator();
    
    int i = 0;
    while (runnersIterator.hasNext()) {
        runnersIterator.next();
 
        assertEquals(runnersIterator.getKey(), this.names[i]);
        assertEquals(runnersIterator.getValue(), this.ages[i]);
        i++;
    }
}

4.4. Removing Elements

4.4.移除元素

Finally, let’s check how an element can be removed by index or by object:

最后,让我们检查一下一个元素如何通过索引或对象来移除

@Test
public void givenALinkedMap_whenElementRemoved_thenSizeDecrease() {
    LinkedMap<String, Integer> lmap 
      = (LinkedMap<String, Integer>) this.runnersLinkedMap;
    
    Integer johnAge = lmap.remove("John");
 
    assertEquals(johnAge, new Integer(36));
    assertEquals(lmap.size(), RUNNERS_COUNT - 1);

    Integer emilyAge = lmap.remove(0);
 
    assertEquals(emilyAge, new Integer(37));
    assertEquals(lmap.size(), RUNNERS_COUNT - 2);
}

5. Provided Implementations

5.提供的实施方案

Currently, in version 4.1 of the library, there are two implementations of the OrderedMap interface – ListOrderedMap and LinkedMap.

目前,在库的4.1版本中,有两个OrderedMap接口的实现 – ListOrderedMapLinkedMap

ListOrderedMap keeps track of the order of the key set using a java.util.List. It is a decorator of OrderedMap and can be created from any Map by using the static method ListOrderedMap.decorate(Map map).

ListOrderedMap使用java.util.List来跟踪键组的顺序。它是OrderedMap的装饰器,可以通过使用静态方法ListOrderedMap.decorate(Map map)从任何Map创建。

LinkedMap is based on a HashMap and improves on it by allowing bidirectional iteration and the other methods of the OrderedMap interface.

LinkedMap是基于HashMap,并通过允许双向迭代和OrderedMap接口的其他方法对其进行改进。

Both implementations also provide three methods that are outside the OrderedMap interface:

这两个实现还提供了三个在OrderedMap接口之外的方法

  • asList() – obtains a list of type List<K> (where K is the type of the keys) preserving the order of the map
  • get(int index) – gets the element at position index as opposed to method get(Object o) provided in the interface
  • indexOf(Object o) – gets the index of the object o in the ordered map

We can cast the OrderedMap into a LinkedMap to use asList() method:

我们可以将OrderedMap转换为LinkedMap,以使用asList()方法。

@Test
public void givenALinkedMap_whenConvertedToList_thenMatchesKeySet() {
    LinkedMap<String, Integer> lmap 
      = (LinkedMap<String, Integer>) this.runnersLinkedMap;
    
    List<String> listKeys = new ArrayList<>();
    listKeys.addAll(this.runnersLinkedMap.keySet());
    List<String> linkedMap = lmap.asList();
 
    assertEquals(listKeys, linkedMap);
}

Then we can check the functioning of method indexOf(Object o) and get(int index) in the LinkedMap implementation:

然后我们可以检查indexOf(Object o)get(int index)方法在LinkedMap实现中的功能。

@Test
public void givenALinkedMap_whenSearchByIndexIsUsed_thenMatchesConstantArray() {
    LinkedMap<String, Integer> lmap 
      = (LinkedMap<String, Integer>) this.runnersLinkedMap;
    
    for (int i = 0; i < RUNNERS_COUNT; i++) {
        String name = lmap.get(i);
 
        assertEquals(name, this.names[i]);
        assertEquals(lmap.indexOf(this.names[i]), i);
    }
}

6. Conclusion

6.结论

In this quick tutorial, we’ve reviewed the OrderedMap interface and its primary methods and implementations.

在这个快速教程中,我们回顾了OrderedMap接口及其主要方法和实现。

For further information, see the JavaDoc of the Apache Commons Collections library.

有关进一步的信息,请参阅Apache Commons集合库的JavaDoc

As always, the complete test class for this article contains similar test cases using both LinkedMap and ListOrderedMap and can be downloaded from the GitHub project.

一如既往,本文的完整测试类包含使用LinkedMapListOrderedMap的类似测试案例,可以从GitHub项目下载。

Next »

Apache Commons Collections BidiMap

« Previous

Apache Commons Collections SetUtils