2016-02-04 10 views
0

У меня есть простой список книг, как этотсравнить элементы в ListIterator

 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: Лихорадка
  • E
  • Elder Scrolls V: Skyrim: Руководство Prima Official Game
  • Взрывоопасные Восемнадцать: A Стефани Плам Роман
  • Я
  • Наследование (Наследование цикла)

Etc ...

Очевидно мне нужно сравнить следующий и предыдущий пункт, поэтому я использовал 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++; 
     } 

Проблема заключается в том, что итератор не работает таким образом, потому что следующий() и предыдущий() метод переходит в следующую/предыдущую итерацию. Они не получают следующее/предыдущее значение, оставаясь в одной и той же итерации

Все советы? Большое спасибо

+0

Сумасшедшая идея - почему бы не вы добавляете заглавные буквы в список перед сортировкой? Если мои серверы памяти правы, одна буква будет помещена перед любой строкой, начинающейся с той же буквы. –

ответ

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

Получить все инициалы, добавить их в список, и порядок:

Set<String> initials = new HashSet<>(); 
for(String title: mItems) { 
    initials.add(title.substring(0, 1)); 
} 
mItems.addAll(initials); 
Collections.sort(mItems); 
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; 
} 
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++;     
    } 

Пусть я знаю, если это работает :)

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 
Смежные вопросы