无需为每个元素

时间:2016-07-12 18:58:36

标签: java iterator

我构建了一个相当简单的程序,它从.txt文件中获取信息并将其放入列表中,对其进行排序,然后通过将其放入TreeSet来删除重复项。

如果查看countInstance()以及如何调用它,您将看到运行该方法的TreeSet的每次迭代,然后多次迭代列表dataToSplit。我认为在这种特定情况下它会重复列表30次。

问题
有没有办法我可以删除多次迭代列表并获得相同结果的需要?

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class TallyCounter {
    private void tallyCount(File commaSeperated) {
        List<String> dataToSplit = new ArrayList<String>();
        Set<String> set;

        try {
            BufferedReader br = new BufferedReader(new FileReader(commaSeperated));
            String currentLine;
            while ((currentLine = br.readLine()) != null) {
                String[] tempArray = currentLine.split(",");
                for(String s : tempArray) {
                    dataToSplit.add(s.replaceAll("\t", "").replaceAll("\n", "").trim());
                }
            }

            br.close();
        } catch(Exception e) {
            e.printStackTrace();
        }

        dataToSplit.sort(new AlphanumComparator());
        set = new TreeSet<String>(dataToSplit);


        System.out.println("String  Tally  Count");
        for(String s : set) {
            System.out.println(countInstance(s, dataToSplit));
        }
    }

    private String countInstance(String s, List<String> l) {
        int count = 0;

        for(String temp : l) {
            if(s.equals(temp)) {
                count++;
            }
        }

        int rSpace = (10 - count) / 2;

        String repeated = new String(new char[count]).replace("\0", "|");
        String space = new String(new char[rSpace]).replace("\0", " ");

        return " " + s + " " + space + repeated + " " + space  + Integer.toString(count);
    }


    public static void main(String[] args) {
        TallyCounter tC = new TallyCounter();
        tC.tallyCount(new File("src/txt.txt"));
    }
}

额外详情

AlphanumComparator.java

import java.util.Comparator;

public class AlphanumComparator implements Comparator<Object>
{
    private final boolean isDigit(char ch)
    {
        return ch >= 48 && ch <= 57;
    }

    /** Length of string is passed in for improved efficiency (only need to calculate it once) **/
    private final String getChunk(String s, int slength, int marker)
    {
        StringBuilder chunk = new StringBuilder();
        char c = s.charAt(marker);
        chunk.append(c);
        marker++;
        if (isDigit(c))
        {
            while (marker < slength)
            {
                c = s.charAt(marker);
                if (!isDigit(c))
                    break;
                chunk.append(c);
                marker++;
            }
        } else
        {
            while (marker < slength)
            {
                c = s.charAt(marker);
                if (isDigit(c))
                    break;
                chunk.append(c);
                marker++;
            }
        }
        return chunk.toString();
    }

    public int compare(Object o1, Object o2)
    {
        if (!(o1 instanceof String) || !(o2 instanceof String))
        {
            return 0;
        }
        String s1 = (String)o1;
        String s2 = (String)o2;

        int thisMarker = 0;
        int thatMarker = 0;
        int s1Length = s1.length();
        int s2Length = s2.length();

        while (thisMarker < s1Length && thatMarker < s2Length)
        {
            String thisChunk = getChunk(s1, s1Length, thisMarker);
            thisMarker += thisChunk.length();

            String thatChunk = getChunk(s2, s2Length, thatMarker);
            thatMarker += thatChunk.length();

            // If both chunks contain numeric characters, sort them numerically
            int result = 0;
            if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0)))
            {
                // Simple chunk comparison by length.
                int thisChunkLength = thisChunk.length();
                result = thisChunkLength - thatChunk.length();
                // If equal, the first different number counts
                if (result == 0)
                {
                    for (int i = 0; i < thisChunkLength; i++)
                    {
                        result = thisChunk.charAt(i) - thatChunk.charAt(i);
                        if (result != 0)
                        {
                            return result;
                        }
                    }
                }
            } else
            {
                result = thisChunk.compareTo(thatChunk);
            }

            if (result != 0)
                return result;
        }

        return s1Length - s2Length;
    }
}

txt.txt

5.00,   5.14,   5.01,   4.90,   5.02,   5.18,   5.04,   5.07,   4.95,   5.05
5.05,   4.82,   4.97,   5.04,   4.98,   5.12,   5.08,   4.96,   5.02,   4.93
5.12,   5.04,   5.13,   4.94,   5.06,   5.00,   4.92,   5.17,   5.08,   4.99
5.07,   5.15,   5.01,   4.95,   5.11,   5.22,   5.08,   4.86,   4.97,   5.14
5.03,   5.14,   5.06,   4.88,   4.96,   5.04,   4.96,   5.09,   4.93,   5.03

脚注

我为输出运行时看起来有多奇怪而道歉。那只是因为我还实现了JTable来存储信息

3 个答案:

答案 0 :(得分:2)

使用HashMap<String,Integer> countMap并迭代字符串一次。对于您找到的每个temp,请在HashMap中的相应值countMap.get(temp)中添加1。

答案 1 :(得分:0)

我建议您使用hash set而不是树集。哈希允许您直接获取所需的数据,而不是遍历所有成员。它具有恒定的插入和查询时间。此外,如果要将每个字符串与其显示的多个实例相关联,则可以使用哈希映射而不是集合,并将字符串映射到Integer

跟你正在做的事情并不是最容易的。你的描述非常简短,没有评论你的代码;我建议你解决这两个问题。分析代码并了解您尝试执行的操作以及尝试执行操作的过程需要花费几分钟时间。如果我们能够立即理解这个问题,你会得到更多帮助。

答案 2 :(得分:0)

我会使用而不是HashMap<String, Integer>HashMap<Double, Integer>

private void tallyCount(File commaSeperated) {
   HashMap<Double, Integer> map = new HashMap<>();

    try {
        BufferedReader br = new BufferedReader(new FileReader(commaSeperated));
        String currentLine;
        while ((currentLine = br.readLine()) != null) {
            String[] tempArray = currentLine.split(",");
            for(String s : tempArray) {
                double value = Double.parseDouble(s);
                if (map.containsKey(value)) {
                    map.replace(value, map.get(value) + 1);
                } else {
                    map.put(value, 1);
                }
            }
        }

        br.close();
    } catch(Exception e) {
        e.printStackTrace();
    }

    map.entrySet().stream()
                  .sorted(Map.Entry.comparingByKey())
                  .forEach(e -> System.out.println(e.getKey() + "|" + e.getValue()));
}


public static void main(String[] args) {
    TallyCounter tC = new TallyCounter();
    tC.tallyCount(new File("src/txt.txt"));
}