2016-12-28 4 views
1

У меня есть проект, в котором основной функцией является чтение .txt-файла в массив String и сортировка его по определенному строковому значению в каждой строке. Мой .txt-файл - это список сотрудников с их именем, зарплатой и опытом. Ниже приведен список моих свидетелей:Сортировка массива String по определенному значению String

  1. Наименование: Thomas Green | Валовая зарплата: 10 000 | Опыт работы: 30 месяцев
  2. Имя: Anna Lang | Валовая зарплата: 6 000 | Опыт: 12 месяцев
  3. Имя: Micheal Holse | Валовая зарплата: 8 000 | Опыт: 27 месяцев

Теперь я хочу сортировать этот список с помощью имени, значения зарплаты или опыта, после использования сканера для изменения этого списка в массив. Я прочитал о компараторе, но не смог найти правильный пример. Как вы видите, что нужно сделать этой программе, это пропустить значение «Имя:» и отсортировать его по алфавиту по имени. Или пропустите другие строки и отсортируйте список по наименьшей зарплате. То же самое для опыта он должен сортировать в течение нескольких месяцев от самого низкого до самого высокого.

Вот что я мог сделать, до сих пор:

import java.io.File; 
import java.io.IOException; 
import java.util.*; 

public class SortList { 
    public static int loadInt() { 
     Scanner s = new Scanner(System.in); 

     if(!s.hasNextInt()) { 
      s.next(); 
      s.nextLine(); 
      return loadInt(); 
     } 
     return s.nextInt(); 
    } 


    public static void main (String[] args) throws IOException{ 
     //show the list 
     String token1 = ""; 
     Scanner inFile1 = new Scanner (new File ("list.txt")).useDelimiter(",\\s*"); 

     List<String> temps = new ArrayList<String>(); 

     while(inFile1.hasNext()) { 
      token1 = inFile1.next(); 
      temps.add(token1); 
     } 
     inFile1.close(); 

     String[] tempsArray = temps.toArray(new String[0]);   
     for(String s : tempsArray) { 
      System.out.println(s); 
     } 

     //Sort the list 

     System.out.println("How do you want to sort?" + "\n" + "1. By name" + "\n" + "2. By salary" + "\n" + "3. By experience"); 
     int b; 
     b = loadInt(); 
     if (b == 1){ 
      ArrayList<String> namesList = new ArrayList<>(); 

      for(int i = 0; i<tempsArray.length; i++){ 
       namesList.add(tempsArray[i]); 
      } 

      Collections.sort(namesList, (name1, name5) -> name1.split(" ")[1].compareTo(name5.split(" ")[1])); 

      for(String name : namesList){ 
       System.out.println(name); 
      } 

     } 
     if (b == 2){ 
      ArrayList<String> salaryList = new ArrayList<>(); 

      for(int i = 0; i<tempsArray.length; i++){ 
       salaryList.add(tempsArray[i]); 
      } 

      Collections.sort(salaryList, (salary1, salary2) -> salary1.split(" ")[10].compareTo(salary2.split(" ")[10])); 

      for(String salary : salaryList){ 
       System.out.println(salary); 
      } 

     } 
     if (b == 3){ 
      ArrayList<String> experienceList = new ArrayList<>(); 

      for(int i = 0; i<tempsArray.length; i++){ 
       experienceList.add(tempsArray[i]); 
      } 

      Collections.sort(experienceList, (experience1, experience2) -> experience1.split(" ")[14].compareTo(experience2.split(" ")[14])); 

      for(String experience : experienceList){ 
       System.out.println(experience); 
      } 
     } 
    } 
}  

На данный момент мой код не сортирует список, когда я вхожу в целое значение. Правильно ли я это делаю? Я нашел пример коллекции через интернет, но это не работает для меня.

+0

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

+0

Спасибо за объяснение. Но если я создам объект под названием Employee, как я собираюсь загрузить список из txt-файла? Я новичок в Java, поэтому я не могу себе представить, как загрузить объект из txt-файла. –

+0

Ничего себе, потратил некоторое время, чтобы написать ответ для вас. Надеюсь, что это поможет, поскольку у меня возникло смутное чувство, что я даже не увижу много преимуществ для этого ... – GhostCat

ответ

4

Правильная вещь, чтобы сделать, это определить Employee объект с firstName, lastName, salary и experience полей. Затем вы можете определить несколько экземпляров Comparator<Employee>, которые поддерживают различные варианты сортировки. Затем вы можете создать List<Employee> и позвонить Collections.sort(), который будет сортировать элементы на основе порядка, определенного Comparator.

Этот класс может выглядеть примерно так:

public class Employee { 
    private final String firstName; 
    private final String lastName; 
    private final int salary; 
    private final int experience; 

    // constructor, getters 
} 

И ваш Comparator может выглядеть примерно так:

public class FirstNameComparator implements Comparator<Employee> { 
    @Override 
    public int compare(Employee e1, Employee e2) { 
    return e1.getFirstName().compareTo(e2.getFirstName()); 
    } 
} 

Или в Java 8 Вы можете использовать ссылку метод и просто передать Comparator.comparing(Employee::getFirstName) к параметру ComparatorCollections.sort().

Тогда это просто вопрос чтения файла и извлечение полей из каждой строки и построение Employee от каждого из них. На этом сайте есть много вопросов, обсуждающих синтаксический анализ данных из текстовых файлов, если вы не уверены в этой части.

+0

+1 для упоминания о решении Java 8 с 'Comparator.comparing'. Большинство людей не знают, с чего начать с реализации компаратора, поэтому готовое решение чрезвычайно полезно. – ifly6

+0

Спасибо за объяснение, однако я должен создать файл с конструктором или выполнить эту часть в моей программе. Итак, лучший вариант - проанализировать данные в сопоставимых полях? –

+0

Боюсь, я не понимаю ваши вопросы.Классы имеют конструкторы, а не файлы; вы можете определить свои компараторы, где бы вы ни хотели - отдельные файлы, вложенные классы внутри 'SortList' или даже как анонимные классы/lambdas. Ключевым моментом является разделение шага синтаксического анализа от этапа сортировки. Разберите текстовый файл в структурированный объект, затем отсортируйте эти объекты. – dimo414

0

Проблема вашего алгоритма заключается в том, что при чтении из файла объект Scanner читает все сразу, а ArrayList темп загружается всего одним элементом. Измените token1 = inFile1.next(); на token1 = inFile1.nextLine();, все остальное в порядке.

0

Дальнейшее улучшение предложения от dimo414. Как сказано, вы создаете класс, который содержит соответствующие части для сотрудника.

Этот класс может иметь конструктор как

public Employee(String firstName, String lastName, int salary, int experienceInMonths) 

и вы бы тогда создать сотрудников как

List<Employee> employees = new ArrayList<>(); 
employees.add(new Employee ("Bilbo", "Beutlin", 5, 10)); 

Но, конечно, ваша дата приходит из файла, который вы говорите, есть такие строки

Name: Thomas Green | Gross salary: 10 000 | Experience: 30 months 

Итак, что вы знаете:

  1. Вы пишете код, который читает, что строки файла по линии
  2. создается вспомогательный метод, который принимает одну такую ​​линию ... и возвращает объект Employee для этого

, как:

public Employee createEmployeeFrom(String line) { 

И в этом методе вы просто должны разобрать эту строку и извлечь соответствующую информацию. Учитывая ваш формат, вы можете сделать:

  • использование String.split («\ |») ..., которые должны разрезать вашу линию в три подстрок
  • Первая подстрока будет «Имя: Thomas Green» тогда. Здесь вы можете использовать String.substring(), чтобы получить все после «:»; давая вам «Томаса Грина». Тогда вы можете предположить, что все, что было после последнего пробела, является фамилией; и что-либо перед тем, как идти первым именем
  • Затем вы делаете аналогичные вещи для частей вашего ввода (используя методы, такие как Integer.valueOf(), чтобы превращать строковые числа в int)
  • Наконец, вы делаете вызов `return new Сотрудник (firstNameParsedFromInput, ....

вещей: вы должны отделить проблемы Одна из проблем является моделирование ваши данные, используя класс Employee, другой задачей является разбор строки для извлечения элементов, которые делают. и только тогда, когда все из этого хорошо работает, вы затем начните поиск в Collections.sort() и напишите свой собственный класс Comparator.

+0

Спасибо за ввод. Я рассмотрю этот подход при написании класса Employee. –

+0

Добро пожаловать. И любезно вспомните мой ответ, как только вы достигнете 15 репутаций и повысите привилегии :-) – GhostCat

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