2015-07-23 3 views
1

У меня есть список имен, которые необходимо преобразовать в результат, чтобы все лица с одинаковой фамилией были помечены. Например: списокКак я могу маркировать дублированные элементы?

Происхождение:

JayReese 
ClaraSmith 
JohnSmith 

выход:

JayReese 
ClaraSmith1 
JohnSmith2 

Код Person класса написано ниже, как я могу сравнить все lastName и когда продублированы lastName, уникальный индекс добавляется к каждому? Какой метод следует добавить?

Я бы очень признателен за любые данные и помощь. Большое спасибо.

import java.util.*; 

public class Person implements Comparable<Person> { 

    private String firstName; 
    private String lastName; 

    public Person(String firstName, String lastName) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    public String toString() { 
     return lastName + firstName; 
    } 
} 
+0

'Person' необходимо будет провести уникальное значение индекса, которое может быть sufixed к выходу. Вам также нужен какой-то поиск, который может управлять «следующим значением», поэтому, если бы существовал другой «Reese», он не стал бы «Reese3», какой-то «Карт» должен сделать трюк. Вам также может потребоваться какой-то способ определить, имеет ли идентификатор 'Person' уже назначенный ему идентификатор unquie, поэтому, если вы запускаете тот же экземпляр' Person' в 'List', вы не увеличиваете свой идентификатор – MadProgrammer

ответ

0

Сначала отредактируйте класс Person или создайте новый класс, который имеет поле индекса, которое могут быть установлены. Сопоставимость совершенно не нужна для вашего использования.

public class Person { 

    private String firstName; 
    private String lastName; 

    public int index; 

    public Person(String firstName, String lastName) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    public String toString() { 
     return lastName + firstName + (index != 0 ? index : ""); 
    } 
} 

Вы можете использовать HashMap<String, Integer> добавить нумерацию к фамилиям, как это:

public static void numberDuplicateLastNames(List<Person> people) { 
    HashMap<String, Integer> duplicatedLastNames = new HashMap<>(); 
    for(Person p : people) { 
     if(! duplicatedLastNames.containsKey(p.lastName)) { 
      duplicatedLastNames.put(p.lastName, 1); 
      p.index = 1; 
     } else { 
      int i = duplicatedLastNames.get(p.lastName) + 1; 
      duplicatedLastNames.put(p.lastName, i); 
      p.index = i; 
     } 
    } 

    //Remove index from the people who don't have a duplicate last name 
    for(Person p : people) { 
     if (duplicatedLastNames.get(p.lastName) == 1) { 
      p.index = 0; 
     } 
    } 
} 
0

Вы могли бы сделать сравнить метод как этот

public compairLastName(String LastName){ 
if(lastName.equals(LastName){ 
System.out.println("These last names are the same"); 
}else{ 
System.out.println("These last names are not the same"); 
} 
0

Таким образом, вы спрашивали о маркировке (и расширением сортировки), но относятся к однозначной идентификации - вот ответ на оба :)

Для сортировки

программы реальной жизни дело с этим каждый день, просто обеспечить ваш сравнимый код по умолчанию сортирует 2 ATTR ibutes

  1. LastName
  2. FirstName

Если сравнивать в таком порядке, вы должны закончить с:

XavierAllen 
JayReese 
BillySmith 
ClaraSmith 
JohnSmith 

Для сравнения нескольких атрибутов, я отсылаю вас к этому StackOverflow тема, в которой показано, как выполнять одиночные и множественные сравнения в объекте Person с одинаковыми именами полей;)

How to compare objects by multiple fields

Для Unique Referance

Кроме того, если вы были обеспокоены однозначно идентифицирующий Person вне простой сортировки сравнения, то вы бы добавить поле Int (или GUID, или независимо от вашего аромат), который сохранил бы уникальную ценность

В принципе то же самое, что и в базе данных PK - вы никогда не использовали бы имя человека как ПК в базе данных, поэтому ваш человек в идеале должен иметь такое же свойство.

Если вы хотите добавить этот ПК к вашему ToString(), а затем пойти на это

import java.util.*; 

public class Person implements Comparable<Person> { 

    private int personID; 
    private String firstName; 
    private String lastName; 

    public Person(String firstName, String lastName, int personID) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
     this.personID = personID; 
    } 

    public int getID(){ 
     return this.personID; 
    } 

    public String toString() { 
     return this.personID + ": " + this.lastName + ", " + this.firstName; 
    } 
} 

@Mshnik сделал опубликовать метод динамического добавления ПК, но вы будете намного лучше проверять коллекцию Person или некоторые переменную высокого уровня, чтобы найти последний идентификатор personID и перейти оттуда - иначе это динамическое значение может использоваться только в самых ограниченных контекстах, и вы можете просто использовать индекс, расположенный в папке Person, который вы извлекаете из

0

Вот перебором способ маркировки ваших Person объектов, которые не полагаются на использование Map с до подсчет фамилий.

У меня также есть другой способ использования мощностей потоков Java 8. ИМО, метод грубой силы более понятен, но я не проводил никаких контрольных испытаний, чтобы узнать, что является более эффективным. Поэтому я оставлю это до комментариев.

public static void main(String[] args) throws Exception { 
    List<Person> persons = new ArrayList() { 
     { 
      add(new Person("Jay", "Reese")); 
      add(new Person("Clara", "Smith")); 
      add(new Person("John", "Smith")); 
      add(new Person("James", "Smith")); 
      add(new Person("Christie", "Mayberry")); 
      add(new Person("Matthew", "Mayberry")); 
     } 
    }; 

    // Toggle calls to see results 
    bruteForceLabel(persons); 
    // java8StreamLabel(persons); 
} 

public static void bruteForceLabel(List<Person> persons) { 
    for (int i = 0; i < persons.size(); i++) { 
     Person currentPerson = persons.get(i); 
     char lastCharacter = currentPerson.lastName.charAt(currentPerson.lastName.length() - 1); 

     // Only process last names that are not labeled 
     if (lastCharacter < '0' || '9' < lastCharacter) { // Not a digit 
      int counter = 2; 
      boolean foundDuplicateLastName = false; 

      for (int j = i + 1; j < persons.size(); j++) { 
       Person nextPerson = persons.get(j); 
       if (nextPerson.lastName.equals(currentPerson.lastName)) { 
        foundDuplicateLastName = true; 

        // Label the next person with the counter then 
        nextPerson.lastName = nextPerson.lastName + counter; 
        counter++; 
       } 
      } 

      // Label the current person with the starting sequence 
      if (foundDuplicateLastName) { 
       currentPerson.lastName = currentPerson.lastName + 1; 
      } 
     } 
    } 

    System.out.println(persons); 
} 

public static void java8StreamLabel(List<Person> persons) { 
    // Get a distinct count of all last names 
    Map<String, Long> lastNames = persons 
      .stream() 
      .map(p -> p.lastName) 
      .distinct() 
      .collect(Collectors 
        .toMap(p -> p, p -> persons 
          .stream() 
          .filter(p2 -> p2.lastName.equals(p)).count())); 

    // Apply number sequence to duplicate last names 
    lastNames.keySet().stream().filter((key) -> (lastNames.get(key) > 1)).forEach((key) -> { 
     int counter = 1; 
     for (Person person : persons.stream().filter(p -> p.lastName.equals(key)).toArray(size -> new Person[size])) { 
      person.lastName = person.lastName + counter; 
      counter++; 
     } 
    }); 

    // Display the modified list 
    System.out.println(persons); 
} 

public static class Person { 

    private String firstName; 
    private String lastName; 

    public Person(String firstName, String lastName) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    public String toString() { 
     return firstName + " " + lastName; 
    } 
} 

Результаты:

[Jay Reese, Clara Smith1, John Smith2, James Smith3, Christie Mayberry1, Matthew Mayberry2] 
Смежные вопросы