【问题标题】:Count and remove similar elements in a list while iterating through it在迭代列表时计算并删除列表中的相似元素
【发布时间】:2017-12-13 07:25:09
【问题描述】:

我在网站上使用了许多参考资料来构建我的程序,但我现在有点卡住了。我认为使用iterator 可以完成这项工作。可悲的是,即使我遇到了带有迭代器的问题,我也无法正确使用它来在我的代码中实现它。

我想, 1.删​​除列表fname中找到的相似元素 2.计数并将fname中找到的每个元素的计数添加到 counter

请帮助我使用迭代器或任何其他方法完成上述操作。以下是我的代码,

List<String> fname = new ArrayList<>(Arrays.asList(fullname.split(""))); //Assigning the string to a list//

    int count = 1;
    ArrayList<Integer> counter = new ArrayList<>();
    List<String> holder = new ArrayList<>();

    for(int element=0; element<=fname.size; element++)
    {
        for(int run=(element+1); run<=fname.size; run++)
        {
            if((fname.get(element)).equals(fname.get(run)))
            {
                count++;
                holder.add(fname.get(run));
            }

            counter.add(count);                    
        }

        holder.add(fname.get(element));
        fname.removeAll(holder);
    }

    System.out.println(fname);
    System.out.println(counter);

谢谢。

【问题讨论】:

  • 给我们一些列表内容的样本
  • @BasilBattikhi list fname : {a, d, e, a, a, f, t, d} 所以列表计数应该是 {3, 2, 1, 1, 1}跨度>
  • 你遇到了什么错误?
  • 或者给我们提供期望输出和你得到了什么

标签: java list add removeall


【解决方案1】:

根据您的问题,您基本上想要:

1.消除给定字符串列表中的重复项

您可以简单地将您的列表转换为HashSet(它不允许重复),然后将其转换回列表(如果您希望最终结果是一个列表,那么您可以用它做其他事情...... )

2。计算列表中出现的所有唯一字词 最快的编码是使用Java 8 Streams(这里借用的代码:How to count the number of occurrences of an element in a List

完整代码

public static void main(String[] args) {
    String fullname = "a b c d a b c"; //something
    List<String> fname = new ArrayList<>(Arrays.asList(fullname.split(" ")));

    // Convert input to Set, and then back to List (your program output)
    Set<String> uniqueNames = new HashSet<>(fname);
    List<String> uniqueNamesInList = new ArrayList<>(uniqueNames);
    System.out.println(uniqueNamesInList);

    // Collects (reduces) your list
    Map<String, Long> counts = fname.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    System.out.println(counts);
}

【讨论】:

  • 您可以使用 keySet() 直接从 Map 中提取 uniqueNames。
  • @GuillaumeF。这是HashSet,而不是HashMap。你确定你能做到吗?
  • @MiguelKVidal Set&lt;String&gt; uniqueNames = counts.keySet(); List 转换也没用,都是 Collections。
  • @GuillaumeF。我查看了文档,在 Set 界面中没有找到这个方法:docs.oracle.com/javase/8/docs/api/java/util/Set.html。你确定你说的不是地图界面 (docs.oracle.com/javase/8/docs/api/java/util/Map.html#keySet--)?
  • @MiguelKVidal 仔细阅读了我的评论,发现我指的是变量counts,即Map
【解决方案2】:

我认为您在这里不需要迭代器。但是,您可以使用许多其他可能的解决方案,例如递归。不过,我刚刚修改了您的代码如下:

    final List<String> fname = new ArrayList<String>(Arrays.asList(fullname.split("")));
    // defining a list that will hold the unique elements.
    final List<String> resultList = new ArrayList<>();
    // defining a list that will hold the number of replication for every item in the fname list; the order here is same to the order in resultList
    final ArrayList<Integer> counter = new ArrayList<>();

    for (int element = 0; element < fname.size(); element++) {
        int count = 1;
        for (int run = (element + 1); run < fname.size(); run++) {
            if ((fname.get(element)).equals(fname.get(run))) {
                count++;
                // we remove the element that has been already counted and return the index one step back to start counting over.
                fname.remove(run--);
            }
        }
        // we add the element to the resulted list and counter of that element
        counter.add(count);
        resultList.add(fname.get(element));
    }
    // here we print out both lists.
    System.out.println(resultList);
    System.out.println(counter);

假设String fullname = "StringOfSomeStaff"; 输出如下:

[S, t, r, i, n, g, O, f, o, m, e, a]
[3, 2, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1]

【讨论】:

  • 我想要类似的东西,如果 {s, t, r, i, n, g, o, f, s, o, m, e, s, t, a, f, f} 是输入它应该生成计数列表为 {3, 2, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1},即,No. of s=3, t=2, r= 1, i=1 等。元素的计数应按照它们在列表中的顺序进行,计数的元素应在计数后立即删除。
  • 我想我按照你说的做了。我没有删除计数的元素,但我不再计数;它只计算一次。
  • 好的,谢谢。我仍然没有尝试代码。我会在核对结果后立即通知您。
  • 抱歉,我尝试了代码,它确实重复计算了元素。只需检查您的示例,首先在“S”下它没有。 3、再次在中间的“S”下它没有。 2. 我数了数。如果它没有被删除,当它遇到以前计数的元素时,它会再次保留相似的元素。
  • 对不起,我没有足够的声望来投票:(
【解决方案3】:

你可以试试这样的:

Set<String> mySet = new HashSet<>();
mySet.addAll( fname ); // Now you have unique values

for(String s : mySet) {
    count = 0;
    for(String x : fname) {
        if( s.equals(x) ) { count++; }
    }
    counter.add( count );
}

这样我们就没有特定的顺序。但我希望它会有所帮助。

在 Java 8 中,有一个单行:

List<Integer> result = fname
    .stream()
    .collect(Collectors.groupingBy(s -> s))
    .entrySet()
    .stream()
    .map(e -> e.getValue().size())
    .collect(Collectors.toList());

【讨论】:

    【解决方案4】:

    我使用 LinkedHashMap 来保留元素的顺序。我正在使用的 for 循环也隐式使用迭代器。代码示例使用Map.merge 方法,该方法从 Java 8 开始可用。

        List<String> fname = new ArrayList<>(Arrays.asList(fullname.split("")));
        /*
            Create Map which will contain pairs kay=values
            (in this case key is a name and value is the counter).
            Here we are using LinkedHashMap (instead of common HashMap)
            to preserve order in which name occurs first time in the list.
        */
        Map<String, Integer> countByName = new LinkedHashMap<>();
        for (String name : fname) {
            /*
                 'merge' method put the key into the map (first parameter 'name').
                 Second parameter is a value which we that to associate with the key
                 Last (3rd) parameter is a function which will merge two values
                 (new and ald) if map already contains this key
             */
            countByName.merge(name, 1, Integer::sum);
        }
        System.out.println(fname);                  // original list [a, d, e, a, a, f, t, d]
        System.out.println(countByName.values());   // counts [3, 2, 1, 1, 1]
        System.out.println(countByName.keySet());   // unique names [a, d, e, f, t]
    

    使用 Stream API 也可以做到这一点,但如果您不熟悉 Streams,可能很难理解。

        Map<String, Long> countByName = fname.stream()
                .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()));
    

    【讨论】:

    • 非常感谢。我在我的代码上进行了尝试,它完全按照我的意愿工作。这是我第一次遇到这个Map 函数。非常感谢。如果可以的话,请添加描述第 2 到第 4 行的注释行,以便我清楚地了解它的作用。
    猜你喜欢
    • 2019-05-02
    • 2014-05-14
    • 2018-07-18
    • 2016-11-21
    • 1970-01-01
    • 2011-04-02
    • 2013-01-23
    • 2020-05-29
    • 1970-01-01
    相关资源
    最近更新 更多