如果需要,比较列表中的项目并替换

时间:2017-09-06 15:03:11

标签: java

我对如何将List中的当前项目与下一项目进行比较并使用新值替换项目存在一些误解。

我有一些代码,但它无法正常工作。

final List<String> items = new ArrayList<>();
items.add("1");
items.add("2");
items.add("3");
items.add("4");
items.add("5");
items.add("6");

public List<String> replaceItems(final List<String> oldList) {
    final List<String> replacedItems = new ArrayList<>();
    for (int i = 0; i < oldList.size(); i++) {
        for (int j = i + 1; j < oldList.size(); j++) {
            if (oldList.get(i).equals(oldList.get(j)) {
               replacedItems.add("replaced");
            } else if (StringUtils.isAnyBlank(oldList.get(i), oldList.get(j))) {
              replacedItems.add("empty");
             }
            replacedItems.add("new value");
        }
      }
   }
}

我的代码中存在一些错误。因为'replacementItems'列表的大小应为== 5,但'replacementItems'的当前大小为45.请帮我解决这个问题。我需要获得与oldList相同大小的replacementItems列表。

3 个答案:

答案 0 :(得分:0)

尺寸问题:

在第二个(嵌套)循环中添加值,这将在每次迭代中执行插入。使用内部循环来确定您当前的值(oldList.get(i))是什么类型(new,empty,duplicated)。你可以通过某种旗帜实现这一目标。之后,您应该在内部循环之后进行一次插入,但仍然在外部循环内。

答案 1 :(得分:0)

您的代码存在的问题是,您会迭代所有项目组合,并为每个此类组合添加新项目,例如replacednew value。相反,您可以使用标记already_seen,如果找到重复项,则将其设置为true,并且只在内循环后添加新元素。但是,这仍然具有二次复杂性。相反,我建议你只使用Set已经看过的元素。您可以使用! add同时添加项目,并查看该项目是否已存在。此外,您可能只想检查当前项目是否为空白,而不是任何组合中的任何项目。

public List<String> replaceItems(List<String> oldList) {
    Set<String> seenItems = new HashSet<>();
    List<String> replacedItems = new ArrayList<>();
    for (String item : oldList) {
        if (! seenItems.add(item)) {
            replacedItems.add("replaced");
        } else if (item.isEmpty()) {
            replacedItems.add("empty");
        } else {
            replacedItems.add("new value");
        }
    }
    return replacedItems;
}

示例:

List<String> items = Arrays.asList("1", "2", "2", "", "5", "5");
System.out.println(replaceItems(items));
// [new value, new value, replaced, empty, new value, replaced]

答案 2 :(得分:0)

你写的程序没有深思熟虑的方法。您必须首先考虑应该在程序中编写的步骤。以下是步骤:

假设oldList和items按照您的意图出现

第1步 - 一次选择一个值(就像你一样)。请参考i(与您一样)

第2步 - 与所有数组元素进行比较,包括步骤1中的数组元素(排除元素i之前的项目)。将其称为j(与您一样)

步骤3 - 检查如果i和j不相等但oldList [i]和oldList [j]相等,则将dupFound设置为true(在步骤2之上将其初始化为false)< / p>

第4步 - 在内循环之后,检查该值是否为空并重复并在此处设置您的值。

我对您的代码进行了一些修改,并将dupFound添加到您的代码中。如果有任何问题,请尝试调试并修复。

    final List<String> replacedItems = new ArrayList<>();
    for (int i = 0; i < oldList.size(); i++) {
        boolean dupFound = false;
        for (int j = 0; j < oldList.size(); j++) {
            if (i != j){
                if (oldList.get(i).equals(oldList.get(j))) {
                    dupFound = true;
                }
            }
        }
        if (dupFound) {
            replacedItems.add("replaced");
        } else if (StringUtils.isEmpty(oldList.get(i))) {
            replacedItems.add("empty");
        } else {
            replacedItems.add("new value");
        }
    }

再补充一点,上述算法假定如果一个数字不止一次存在,那么它的所有值都将显示为已替换。如果您希望将第一个标记为新值,则必须将上述算法更改为:

第1步 - 一次选择一个值(就像你一样)。请参考i(与您一样)

步骤2 - 检查元素0到i-1之间的数组中是否存在该值。如果是,则将boolean newVal设置为false(在步骤2之上将其初始化为true)

第3步 - 如果oldList [i]为空,如果newVal为true,则添加空的else,将“new value”添加到数组,否则添加替换

这是实现此目的的修改版本:

    for (int i = 0; i < oldList.size(); i++) {
        boolean newVal = true;
        for (int j = 0; j < i; j++){
            if (oldList.get(i).equals(oldList.get(j))){
                newVal = false;
            }
        }

        if (StringUtils.isEmpty(oldList.get(i))){
            replacedItems.add("empty");
        } else if (newVal) {
            replacedItems.add("new value");
        } else {
            replacedItems.add("replaced");
        }

    }

随意玩一下数组,并尝试先将其作为算法编写。相信我有帮助。