比较listIterator中的元素

时间:2016-02-04 16:14:43

标签: java loops iterator

我有一个简单的书籍列表

        mItems.add("Steve Jobs");
        mItems.add("Inheritance (The Inheritance Cycle)");
        mItems.add("The Hunger Games");
        mItems.add("The LEGO Ideas Book");
        mItems.add("Catching Fire (The Second Book of the Hunger Games)");
        mItems.add("Death Comes to Pemberley");
        mItems.add("Diary of a Wimpy Kid 6: Cabin Fever");
        mItems.add("Explosive Eighteen: A Stephanie Plum Novel");
        mItems.add("Elder Scrolls V: Skyrim: Prima Official Game Guide");

我希望通过在下一本书以不同的字母开头时添加标题来按字母顺序重新组织列表

所以最终的名单应该是这样的

  • C
  • 着火(饥饿游戏的第二本书)
  • d
  • 死亡来到彭伯利
  • 一个懦弱的孩子的日记6:小屋发烧
  • 电子
  • Elder Scrolls V:Skyrim:Prima官方游戏指南
  • 爆炸十八:斯蒂芬妮梅花小说
  • I
  • 继承(继承周期)

等等...

显然我需要比较下一个和上一个项目,所以我使用了ListIterator

mItems = new ArrayList<String>();
        mItems.add("Steve Jobs");
        mItems.add("Inheritance (The Inheritance Cycle)");
        mItems.add("The Hunger Games");
        mItems.add("The LEGO Ideas Book");
        mItems.add("Catching Fire (The Second Book of the Hunger Games)");
        mItems.add("Death Comes to Pemberley");
        mItems.add("Diary of a Wimpy Kid 6: Cabin Fever");
        mItems.add("Explosive Eighteen: A Stephanie Plum Novel");
        mItems.add("Elder Scrolls V: Skyrim: Prima Official Game Guide");
        Collections.sort(mItems);

        ArrayList<Book> books= new ArrayList<Book>();
        int position = 0;
        boolean isSeparator = false;
        ListIterator<String> it = mItems.listIterator();

        while(it.hasNext()) {
            isSeparator = false;

            String name = it.next();

            char[] nameArray;

            // If it is the first item then need a separator
            if (position == 0) {
                isSeparator = true;
                nameArray = name.toCharArray();
            }
            else {
                // Get the previous book's name
                String previousName =  it.previous();

                // Convert the previous and current book names
                // into char arrays
                char[] previousNameArray = previousName.toCharArray();
                nameArray = name.toCharArray();

                // Compare the first character of previous book and current book,
                if (nameArray[0] != previousNameArray[0]) {
                    isSeparator = true;
                }


                // go next item
                it.next();
            }

           // item is a separator
            if (isSeparator) {
                Book book= new Contact(String.valueOf(nameArray[0]), null, isSeparator);
                books.add( book);
            }

            // Create a Book object to store the name and if it's a separator or not
            Book book= new Book (name, null, false);
            books.add( book);

            position++;
        }

问题在于Iterator没有以这种方式工作,因为next()和previous()方法在下一个/上一个迭代中跳转。 他们在同一次迭代中不会获得下一个/上一个值

有什么建议吗? 非常感谢你

5 个答案:

答案 0 :(得分:2)

获取所有首字母,将它们添加到列表中,然后排序:

{{1}}

答案 1 :(得分:1)

如果您将已排序的列表包装在Iterable中,您可以自己添加额外的部分。

private static class InitialedList implements Iterable<String> {

    final List<String> items;

    public InitialedList(List<String> mItems) {
        this.items = mItems;
    }

    @Override
    public Iterator<String> iterator() {
        return new Iterator<String>() {
            Iterator<String> i = items.iterator();
            // The next from the list.
            String next = null;
            // The last one we delivered.
            String last = null;

            @Override
            public boolean hasNext() {
                return next != null || i.hasNext();
            }

            @Override
            public String next() {
                // Peek at the next.
                if (next == null) {
                    next = i.next();
                }
                // What to return.
                String it = null;
                // Is there a change in initial?
                if (next != null) {
                    // Behaviour undefined if empty string in list.
                    if (last == null || last.charAt(0) != next.charAt(0)) {
                        it = next.substring(0, 1);
                    } else {
                        it = next;
                        next = null;
                    }
                }
                return last = it;
            }

        };
    }
}

public void test() {
    List<String> mItems = new ArrayList<>();
    mItems.add("Steve Jobs");
    mItems.add("Inheritance (The Inheritance Cycle)");
    mItems.add("The Hunger Games");
    mItems.add("The LEGO Ideas Book");
    mItems.add("Catching Fire (The Second Book of the Hunger Games)");
    mItems.add("Death Comes to Pemberley");
    mItems.add("Diary of a Wimpy Kid 6: Cabin Fever");
    mItems.add("Explosive Eighteen: A Stephanie Plum Novel");
    mItems.add("Elder Scrolls V: Skyrim: Prima Official Game Guide");
    Collections.sort(mItems);
    for (String s : new InitialedList(mItems)) {
        System.out.println(s);
    }
}

打印:

C
Catching Fire (The Second Book of the Hunger Games)
D
Death Comes to Pemberley
Diary of a Wimpy Kid 6: Cabin Fever
E
Elder Scrolls V: Skyrim: Prima Official Game Guide
Explosive Eighteen: A Stephanie Plum Novel
I
Inheritance (The Inheritance Cycle)
S
Steve Jobs
T
The Hunger Games
The LEGO Ideas Book

答案 2 :(得分:1)

如果你使用的是java 8:

List<String> newItems = mItems.stream()
    .flatMap(s -> Stream.of(s.substring(0, 1), s))
    .distinct()
    .sorted()
    .collect(toList());

现在newItems包含以下内容:

C
Catching Fire (The Second Book of the Hunger Games)
D
Death Comes to Pemberley
Diary of a Wimpy Kid 6: Cabin Fever
E
Explosive Eighteen: A Stephanie Plum Novel
Elder Scrolls V: Skyrim: Prima Official Game Guide
I
Inheritance (The Inheritance Cycle)
S
Steve Jobs
T
The Hunger Games
The LEGO Ideas Book

答案 3 :(得分:0)

只需存储并比较之前和当前元素:

String prev = null;
String curr = null;
char c;
while(it.hasNext()) {
    curr = it.next();
    if (prev == null || prev.charAt(0) != curr.charAt(0)) {
        c = curr.charAt(0);
    }

    // Do what you need to do with current name 'curr' and initial character 'c'

    prev = curr;
}

答案 4 :(得分:0)

    ListIterator<String> it = mItems.listIterator();
    int i = 0;
    String [] listOfFirstChars = new String[26];
    int indexForAddingCharacter = 0;
    while(it.hasNext()) {              
          String firstChar = it.next().subString(0,1);
          if(firstChar != listOfFirstChars[indexForAddingCharacter]){
          listOfFirstChars[indexForAddingCharacter] = firstChar;
          indexForAddingCharacter++;
          mItems.add(i, firstChar);
          }
    i++;                 
    }

让我知道这是否有效:)