在迭代过程中计算并删除列表中的类似元素

时间:2017-07-09 13:55:40

标签: java list add removeall

我在网站上使用了很多引用来构建我的程序,但我现在有点卡住了。我认为使用iterator可以完成这项工作。可悲的是,即使我经历了有迭代器的问题,我也无法正确使用它来在我的代码上实现它。

我想,       1.删​​除列表fname中找到的类似元素       数数与数量将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);

感谢。

4 个答案:

答案 0 :(得分:2)

从你的问题来看,你基本上想要:

<强> 1。消除给定字符串列表中的重复项

您只需将列表转换为HashSet(它不允许重复),然后将其转换回列表(如果您希望最终结果为List,那么您可以执行其他操作它...)

<强> 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);
}

答案 1 :(得分:0)

您可以尝试这样的事情:

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());

答案 2 :(得分:0)

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

    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]

答案 3 :(得分:0)

我使用的是LinkedHashMap来保存元素的顺序。对于我正在使用的循环,隐式使用Iterator。代码示例使用的是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()));