计数时间属性“ ABC”值在集合中已更改

时间:2019-10-06 01:41:35

标签: java list count java-stream aggregate

我当前正在使用Java 8,并且无法切换到更高版本。由于我找不到类似的东西,因此也许有人知道已经实施的解决方案。它可以是第三方库,也可以使用lambda等。没有限制。任何帮助表示赞赏!

有一个具有这种结构的列表,例如:

| ID | Date       | Status | Name | Description      | Currency |
|----|------------|--------|------|------------------|----------|
| 1  | 2019-10-01 | 1      | 'A'  | 'Description A'  | USD      |
| 1  | 2019-10-01 | 3      | 'A'  | 'Description A2' | USD      |
| 1  | 2019-10-01 | 4      | 'A2' | 'Description A2' | USD      |
| 2  | 2019-10-03 | 1      | 'B'  | 'Description B'  | USD      |
| 2  | 2019-10-03 | 2      | 'B'  | 'Description B'  | BRL      |
| 2  | 2019-10-03 | 4      | 'B'  | 'Description B'  | USD      |
| 3  | 2019-10-05 | 1      | 'C'  | 'Description C'  | JPY      |
| 3  | 2019-10-05 | 2      | 'C'  | 'Description C2' | JPY      |

问题是基于具有以下字段的原始列表创建另一个列表:

  1. 日期;
  2. ID;
  3. 时间状态已更改;
  4. 时间名称或描述已更改;
  5. 时代货币已更改;

此外,还需要更多字段(如果这使问题过于复杂,我可以将其分为其他问题):

  1. 从上次更改日期到特定ID的第一个日期之间的天数(称为“老化”);

  2. 显示更改的类型:

7.1“名称/描述”(仅更改名称或描述)

如果仅更改了货币,则为7.2“货币”

7.3如果名称或说明和币种发生变化,则均为“ ”

不一定要成为List。它可以是任何类型的集合。

第一个列表来自一个SQL查询。那就是我开始编写的代码:

public List<Obj> getResultList() {
    List<Obj> resultList = new ArrayList<>();
    Map<String, Integer> counterMap = new HashMap<>();

    counterMap.put("status", 0);
    counterMap.put("name", 0);
    counterMap.put("description", 0);
    counterMap.put("currency", 0);

    StreamEx.of(sourceList).forPairs((current, next) -> {
        compareCurrentAndNext(current, next);
    });

    int countStatus = counterMap.get("status");

    // etc
}

private void compareCurrentAndNext(final Obj current,
                                   final Obj next) {
    if (current.getId().equals(next.getId())) {
        if (!current.getStatus().equals(next.getStatus())) {
            counterMap.replace("status", counterMap.get("status") + 1);
        }

        // etc
    }
}

它使用StreamEx库(https://github.com/amaembo/streamex):

<dependency>
  <groupId>one.util</groupId>
  <artifactId>streamex</artifactId>
  <version>0.7.0</version>
</dependency>

实际上,还有更多的属性,我在这里简化了真正的问题。

1 个答案:

答案 0 :(得分:0)

如果您要一个新列表(const usePos = () => { const [pos, setPos] = useState({lat: "", long: ""}) const getLocation = () => { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(getCoords) } else { alert('GeoLocation not enabled'); } } const getCoords = (pos) => { console.log(pos) setPos({ lat: pos.coords.latitude, long: pos.coords.longitude }) } getLocation() return { lat: pos.lat, long: pos.long } } const App = () => { const pos = usePos() return ( <div> <p>Lat {pos.lat}</p> <p>Long: {pos.long}</p> </div> ) } ),并且列表中的每个条目都具有5个(或更多)属性,则应从创建具有5个(或更多)字段的类开始。

这不是称为resultList的类(BTW确实是一个坏名字),因为结果属性与源属性不同。此类的定义对于您的代码很重要,因此您需要对其进行定义。

然后,当您迭代原始列表(Obj)时,当sourceListDate发生更改时,您将创建一个新的结果对象并将其添加到结果列表中。如果IDDate相同,则可以根据需要比较和增加变更计数器。

关于物业6,我不确定我是否了解其要求,因此,我会让您着手进行。

对于属性7,它实际上是从属性4和5派生的属性,因此可以将其实现为结果类的getter方法,并从两个计数器字段中获取其值。