2015-05-09 2 views
5

для Java практике, я пытаюсь создать метод в моем EmployeesDirectory класса, что:Удаление повторяющихся записей в массиве - Java

  • Удаляет повторяющиеся записи из массива
  • Массив должен быть такой же длины, после того, как удаление дубликатов
  • непустые элементы должны быть сделать непрерывную последовательность в начале массива - и actualNum должны вести учет записей

Дублированный Средства: же имя, должность и зарплата

Вот мой текущий код:

Я не уверен в том, как реализовать это - любая помощь была бы оценена

class EmployeeDirectory { 

    private Employee dir[]; 
    private int size; 
    private int actualNum; 

    public EmployeeDirectory(int n) { 
     this.size = n; 
     dir = new Employee[size]; 
    } 

    public boolean add(String name, String position, double salary) { 
     if (dir[size-1] != null) { 
      dir[actualNum] = new Employee(name, position, salary); 
      actualNum++; 
      return true; 
     } else { 
      return false; 
     } 
    } 
} 
+0

удаления дубликатов записей !! Вы имеете в виду удалить дубликатов сотрудников с тем же именем? – MChaker

+0

@MChaker они означают объекты, для которых 'a.equals (b) == true' –

ответ

4

Я бы предпочел, чтобы вы не написал отдельный метод удаления дубликатов. Если бы я был вами, я бы искал дубликаты в методе add, а затем сразу же решил, нужно ли мне добавить Employee.

Кроме того, почему вы не используете Sets (ссылка для HashSet) вместо массивов для вашей цели? Наборы по их собственному Запрещает определение добавляющих дубликатов, поэтому они, как представляются целесообразными в качестве решения

+0

Набор не всегда полезен, так как он разбивает порядок элементов. Но Set полезен при итерации массива для сбора отдельных объектов. –

+1

@SashaSalauyou, если вам нужен тот же порядок элементов, что и порядок их вставки, есть [LinkedHashSet] (http://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashSet .html), чтобы достичь этого :) –

+0

С 'LinkedHashSet' вы теряете возможность запрашивать элемент по индексу в O (1). –

1

Если ваши состояния задачи, как «удалить дубликаты из массива» (т.е. вы не можете использовать ArrayList или управление при добавлении элементов), вы можете использовать следующий подход:

public void removeDuplicates() { 
    Set<Employee> d = new HashSet<>(); // here to store distinct items 
    int shift = 0; 
    for (int i = 0; i > dir.length; i++) { 
     if (d.contains(dir[i])) {  // duplicate, shift += 1 
      shift++; 
     } else {      // distinct 
      d.add(dir[i]);    // copy to `d` set 
      dir[i - shift] = dir[i]; // move item left 
     } 
    } 
    for (int i = d.size(); i < dir.length; i++) 
     dir[i] = null;     // fill rest of array with nulls 

    actualNum = d.size(); 
} 

Здесь shift переменная хранит число дубликатов, обнаруженных в массиве до сих пор. Каждый отдельный элемент перемещается на shift позиций слева, чтобы сделать последовательность непрерывной, сохраняя начальный порядок. Затем остальные элементы изменяются до нулей.

Для того, чтобы хэш на основе коллекции работать с Employee экземплярами правильно, также необходимо переопределить hashCode() и equals() методы следующим образом:

public class Employee { 

    //... 

    @Override 
    public int hashCode() { 
     return Objects.hash(name, position, salary); 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null) return false; 
     if (!o.getType().equals(this.getType()) return false; 
     Employee e = (Employee) o; 
     return Objects.equals(e.name, name) 
      && Objects.equals(e.position, position) 
      && Objects.equals(e.salary, salary); // or e.salary == salary, if it primitive type 
    } 
} 
+0

Назначение одиночного символа в качестве имени ссылки является плохой практикой. Имена ссылок должны иметь смысл. Кроме того, вы, вероятно, не получили то, что наборы. Наборы НЕ МОГУТ содержать равные объекты. –

+0

* «Вы, вероятно, не получили то, что наборы» * - извините, я не могу продолжить обсуждение, это такая крутая манера ... –

+0

Я не хотел вас обидеть, но сам установил «пропускает» все объекты, которые он уже содержит. На данный момент ваш код не имеет смысла. Прочитайте документы. Извините –

2

К сожалению, я не получил класс Employee, чтобы проверить мой код, но попробуйте следующее:

void removeDuplicates() { 
    int length = dir.length; 
    HashSet set = new HashSet(Arrays.asList(dir)); 
    dir = new Employee[length]; 
    Employee[] temp = (Employee[]) set.toArray(); 
    for (int index = 0; index < temp.length; index++) 
     dir[index] = temp[index]; 
} 

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

import java.util.Arrays; 
import java.util.HashSet; 
3

Прежде всего, Overrideequals и hashCode методы в Employee классе, как следовать

@Override 
public boolean equals(Object other) { 
    if(this == other) return true; 

    if(other == null || (this.getClass() != other.getClass())){ 
     return false; 
    } 

    Employee guest = (Employee) other; 
    return Objects.equals(guest.name, name) 
      && Objects.equals(guest.position, position) 
      && Objects.equals(guest.salary, salary); 
} 

@Override 
public int hashCode() { 
    return Arrays.hashCode(new Object[] { 
       name, 
       position, 
       salary 
     }); 
} 

Затем вы можете использовать класс, сформированный с учетом способностей учащихся API distinct метод для удаления дубликатов

Возвраты поток, состоящий из отдельных элементов (согласно Object.equals (Object)) этого потока.

Вы можете сделать это так

Employee e1 = new Employee("John", "developer", 2000); 
Employee e2 = new Employee("John", "developer", 2000); 
Employee e3 = new Employee("Fres", "designer", 1500); 

Employee[] allEmployees = new Employee[100]; 
allEmployees[0] = e1; 
allEmployees[1] = e2; 
allEmployees[2] = e3; 

allEmployees = Arrays.asList(allEmployees).stream().distinct() 
      .toArray(Employee[]::new); 

Arrays.asList(allEmployees).forEach(System.out::println); 

Выходные: (сохраняя как пустые и непустые записей)

John developer 2000.0 
Fres designer 1500.0 
null 
+0

@SashaSalauyou Что вы думаете об этом ответе? – MChaker

+0

Я думаю, что это неплохо (я тоже люблю java 8 функций), но ваш метод 'equals()' подвержен ошибкам, если только 'name' и' position' не гарантируются как ненулевые. –

+0

и ваш 'hashCode()' очень плохой, обычно он объединяется всеми нестатическими свойствами объекта. –

Смежные вопросы