Сбор данных с карты в список с использованием Java 8 - PullRequest
1 голос
/ 02 июня 2019

Пожалуйста, помогите мне с картой Java 8 - фильтр - сортировка - сбор кода.

Info.java

public class Info {
private final String name;
private final String desc;
private String version = null;

@Override
public boolean equals(Object that) {
    if (that == null) {
        return false;
    }

    if (that instanceof Info) {
        Info other = (Info) that;

        return Objects.equals(this.name, other.name) &&
                Objects.equals(this.desc, other.desc) &&
                Objects.equals(this.version, other.version);

    } else {
        return false;
    }
}

public boolean equalsWithoutVersion(Object that) {
    if (that == null) {
        return false;
    }

    if (that instanceof Info) {
        Info other = (Info) that;

        return Objects.equals(this.name, other.name) &&
                Objects.equals(this.desc, other.desc);
    } else {
        return false;
    }
}

@Override
public int hashCode() {
    int hash = 13;
    hash = (hash * 7) + name.hashCode();
    hash = (hash * 7) + desc.hashCode();

    if (version != null)
        hash = (hash * 7) + version.hashCode();

    return hash;
}

@Override
public String toString() {
    String versionString = version == null ? "latest" : version;
    return String.format("Name: %s  Desc: %s  Key Type: %s Version: %s", this.name, this.desc, this.keyType.name(), versionString);
}
}  

Value.java

public class Value implements Comparable<Value> {
private String data;
private String version;

public Value(String version, String data) {
    this.version = version;
    this.data = data;
}

@Override
public int compareTo(Value o) {
    return (Integer.parseInt(this.version) > Integer.parseInt(o.version)) ? -1
            : (Integer.parseInt(this.version) < Integer.parseInt(o.version)) ? 1
            : 0;
}
}

Cache.java

public class Cache {
    private final Map<Info, Value> dataMap = new HashMap<>();

    ...
    private Value getlatestVersionFromCache(Info info) {
    List<Value> values = dataMap.entrySet().stream()
            .filter(p -> p.getKey().equalsWithoutVersion(info))
            .sorted(Map.Entry.comparingByValue())
            .map(x::getValue))
            .collect(Collectors.toList());
    return values.isEmpty() ? null : values.get(0);
}
} 

Цель - получить последнюю версию записи с карты.Итак, сначала я фильтрую записи с карты, сравнивая поля Info без версии.Затем я сортирую карту по значению в зависимости от версии.Затем я собираю значения в список.Затем я могу получить первый элемент, чтобы получить последнюю версию.

Но я получаю следующую ошибку компиляции в операторе фильтра:

Syntax error on token ")", ElidedSemicolonAndRightBrace expected

Ответы [ 3 ]

1 голос
/ 02 июня 2019

Ну, я сомневаюсь в вашем решении. Я думаю, что вы можете сделать это простым способом. поэтому сначала измените тип version на Integer в классе Value ( в методе compareTo (), который вы преобразовали в Integer ). а также измените сигнатуру метода на Optional<Value> в getlatestVersionFromCache() методе.

также я думаю, вам не нужно сортировать dataMap.

private Optional<Value> getlatestVersionFromCache(Info info) {
     Map<Value,Integer> result = dataMap.entrySet()
            .stream()
            .filter(p -> p.getKey().equalsWithoutVersion(info))
            .collect(Collectors.toMap(Map.Entry::getValue, entry -> entry.getValue().getVersion(), Integer::min));

   Optional<Value> latestValue = result.keySet()
           .stream()
           .min(Comparator.comparingInt(key -> key.getVersion()));

     return latestValue;
}

Лучшее решение - что-то вроде этого:

dataMap.entrySet()
            .stream()
            .filter(p -> p.getKey().equalsWithoutVersion(info))
            .min(Comparator.comparingInt(entry -> entry.getValue().getVersion()))
            .map(Map.Entry::getValue)
            .orElse(null);
1 голос
/ 02 июня 2019

У вас есть несколько пропусков и ошибок в коде, который вы разместили, но оператор filter на самом деле был в порядке.

Следующая компиляция проходит:

List<Value> values = dataMap.entrySet()
        .stream()
        .filter(p -> p.getKey().equalsWithoutVersion(info))
        .sorted(Map.Entry.comparingByValue())
        .map(Map.Entry::getValue) // was .map(x::getValue)) - x is not defined anywhere, so
                                  // I assumed you meant Map.Entry::getValue
        .collect(Collectors.toList());
0 голосов
/ 02 июня 2019
class Info {

    public static final BiPredicate<Info, Info> IS_EQUAL_IGNORE_VERSION =
            (one, two) -> one.getName().equals(two.getName()) && one.getDesc().equals(two.getDesc());

    private final String name;
    private final String desc;
    private String version;
}


private final Map<Info, Value> dataMap = new HashMap<>();

public Value getlatestVersionFromCache(Info info) {
    Value value = null;

    for (Map.Entry<Info, Value> entry : dataMap.entrySet())
        if (Info.IS_EQUAL_IGNORE_VERSION.test(entry.getKey(), info))
            if (value == null || Integer.parseInt(entry.getValue().getVersion()) > Integer.parseInt(value.getVersion()))
                value = entry.getValue();

    return value;
}

Примечания:

  1. Я думаю, что использовать компаратор, чтобы проверить, что два объекта являются qual, не правильно. Вы можете использовать, например, Predicate. И определите его как статический метод в целевом классе.
  2. Обратите внимание на version. Кажется, что это должно быть целое число вместо String.
  3. В вашем подходе сравнивать две строки некорректно, потому что она используется вместо equals метода.
  4. Я думаю, что использование Java8 потоков только потому, что это поток, не является правильным.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...