在地图中为每个键获取重复值

时间:2016-07-27 11:19:11

标签: java

我试图将所有值放在地图中,我有超过20k的值,现在我试图通过使用想法将值放在地图中,因为键1包含从1(考虑到i)到1000(即i * 1000)的值)但我得到的输出包含重复值(键1和2具有相同的值),不确定我在做什么错误

这是代码

 public class GetNumbers {

        public static List<String> createList() throws IOException {
            List<String> numbers = new LinkedList<>();
            Path path = null;
            File file = null;
            BufferedReader reader = null;
            String read = "";
            try {
                path = Paths.get("file.txt");
                file = path.toFile();
                reader = new BufferedReader(new FileReader(file));
                while ((read = reader.readLine()) != null) {
                    numbers.add(read);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            return numbers;
        }

        public static Map<Integer, List<String>> createNewFiles() throws IOException {
            Map<Integer, List<String>> myMap = new HashMap<>();
            List<String> getList = GetNumbers.createList();
            List<String> list = null;
            int count = getList.size() / 1000;
---------------------------doubt full code-----------------------------------
            for (int i = 1; i <= count; i++) {
                if (getList.size() > 1000) {
                    list = getList.subList(i, i * 1000);
                } else if (getList.size() < 999) {
                    list = getList.subList(i, getList.size());
                }
-----------------------------------------------------------------------------
                myMap.put(i, list);
            }
            return myMap;

        }

        public static void getMap() throws IOException {
            Map<Integer, List<String>> map = GetNumbers.createNewFiles();
            List<String> listAtIndexOne = map.get(2);
            List<String> listAtIndexTwo = map.get(1);
            for (String elementFromFirstList : listAtIndexOne) {
                for (String elementFromSecondList : listAtIndexTwo) {
                    if (elementFromFirstList.equals(elementFromSecondList)) {
                        System.out.println("duplicate copy");
                    }
                }
            }

        }

        public static void main(String[] args) {
            try {
                GetNumbers.getMap();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

修改

如果我将我的代码更改为

for (int i = 0; i <= count; i++) {
            if (getList.size() > (i * 1000)) {
                list = getList.subList(i, (i + 1) * 1000);
            } else if (getList.size() < 999) {
                list = getList.subList(i, getList.size());
            }
            myMap.put(i, list);
        }

我正在

  

线程中的异常&#34; main&#34; java.lang.IndexOutOfBoundsException:   java.util.SubList中的toIndex = 25000。(未知来源)at   java.util.AbstractList.subList(未知来源)at   com.dnd.GetNumbers.createNewFiles(GetNumbers.java:43)at   com.dnd.GetNumbers.getMap(GetNumbers.java:54)at   com.dnd.GetNumbers.main(GetNumbers.java:69)

感谢任何帮助

谢谢

2 个答案:

答案 0 :(得分:2)

我会改变一些事情,但这一行中有一个错误

subList(i, i * 1000);

您首先在1 to 1000处开始列表,忽略0处的值,但忽略您正在执行的第二次迭代2 to 2000等。

在此之后,您最有可能的是0 to 9991000 to 1999。 BTW在LinkedList上执行子列表是非常低效的。

我会在您阅读文件时构建这些列表。

我会像这样写

public static void splitFile(String inputFile, String outputTemplate, int count) throws IOException {
    int fileCount = 0, lineCount = 0;
    // check for duplicates.
    Set<String> previous = new HashSet<>();
    // file to write to
    PrintWriter pw = null;
    // file to read from
    try (BufferedReader in = new BufferedReader(new FileReader(inputFile))) {
        // while there is another line to read.
        for (String line; (line = in.readLine()) != null; ) {
            // skip duplicates.
            if (!previous.add(line))
                continue;
            // if we are at the end or haven't start a file.
            if (pw == null || lineCount++ >= count) {
                // close the old on if there was one.
                if (pw != null)
                    pw.close();
                // start a new file using the template i.e. where do we put the number.
                pw = new PrintWriter(String.format(outputTemplate, fileCount++));
                // we will have one line in this file.
                lineCount = 1;
            }
            // add the line.
            pw.println(line);
        }
    }
    // close the file if we had one left open.
    if (pw != null)
        pw.close();
}

public static void main(String[] args) throws IOException {
    // split the file into multiple files with up to 1000 lines each.
    splitFile("file.txt", "file-part-%n.txt", 1000);
}

答案 1 :(得分:2)

要将列表拆分为1000个元素的子列表,您可以编写如下内容:

        for (int i = 1; i <= count; i++) {
            if (getList.size() >= i*1000) {
                list = getList.subList((i-1) * 1000, i * 1000);
            } else {
                list = getList.subList((i-1) * 1000, getList.size());
            }
            myMap.put(i, list);
        }

或更简单:

        for (int i = 1; i <= count; i++) {
            list = getList.subList((i-1) * 1000, Math.min(getList.size(),i * 1000));
            myMap.put(i, list);
        }

请注意,索引是基于0的,因此第一个子列表将是0到999,第二个是1000到1999,依此类推。