#java #arrays #class #object #instance
#java #массивы #класс #объект #экземпляр
Вопрос:
Я пишу программу, в которой мне нужно подсчитать золотые медали для каждой страны. Входные данные будут поступать из файла, и я должен обработать файл. Первая строка — это код страны, вторая строка — тип события, а третья — событие. Входные данные выглядят следующим образом:
CHN
Diving
Women's 10m Platform
CAN
Rowing
Men's Eight
CHN
Rowing
Women's Quadruple Sculls
Ожидаемый результат должен быть таким:
Count of gold medallists by country:
CHN - 2
CAN - 1
Count of gold medallists by event type:
Diving - 1
Rowing - 2
Итак, я создал класс золотых медалей, в котором он создаст новый объект экземпляра для каждой страны в соответствии с типом события. Мой код здесь:
class GoldMedals {
private String country;
private String eventType;
private String event;
private int medalCount;
public GoldMedals(String name, String type, String event) {
this.country = name;
this.eventType = type;
this.event = event;
medalCount = 1;
}
public boolean matchDetails(String countryName, String type){
return (country.equals(countryName) amp;amp; eventType.equals(type));
}
Мой основной метод здесь:
try {
input = new BufferedReader(new FileReader ("textfile.txt"));
country = input.readLine();
while(country!=null) {
eventType = input.readLine();
event = input.readLine();
match = findMatch(winners, size, country, eventType);
if(match == null) {
winners[size] = new GoldMedals(country, eventType, event);
size ;
//match.addMedal();
} //else {
//match.addMedal();
//}
//match.addMedal();
country = input.readLine();
}
input.close();
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
Я также добавил статический метод, который гарантирует, что мы не создаем объекты, которые уже существуют. (избыточные объекты)
public static GoldMedals findMatch(GoldMedals[] winners, int size, String country, String type) {
GoldMedals result = null;
int pos;
pos = 0;
while (pos < size amp;amp; result == null) {
if (winners[pos].matchDetails(country, type)) {
result = winners[pos];
} else {
pos ;
}
}
return resu<
}
Что я хочу знать, так это как я могу получить требуемый результат. Потому что прямо сейчас я получаю этот вывод:
ITA- 1- Fencing- Women's Individual Foil
POL- 1- Rowing- Men's Quadruple Sculls
KEN- 1- Athletics- Men's Marathon
CHN- 1- Diving- Men's 3m Springboard
TUN- 1- Swimming- Men's 1500m Freestyle
CHN- 1- Canoe/Kayak - Flatwater- Canoe Double (C2) 500m Men
CHN- 1- Diving- Men's Synchronised 3m Springboard
USA- 1- Gymnastics Artistic- Women's Individual All-Around
RUS- 1- Synchronized Swimming- Duet
это то, что я запрограммировал. Мне нужна помощь в том, как я могу получить общее количество золотых медалей для каждой страны, а также золотые медали в зависимости от типа события. Короче говоря, как я могу получить желаемый результат, который указан выше.
Я могу подробнее объяснить, если вам нужна помощь с моим вопросом. Подсказки будут оценены по достоинству.
Комментарии:
1. Самый простой способ — иметь 2 карты. Первый, у которого есть строка типа страны в качестве ключа и целое число для подсчета медалей в качестве значения. Вторая карта должна содержать строку события для ключа и целочисленный счетчик для значения. Чем зацикливать файл, вы будете суммировать медали по стране и событию. В конце цикла на 2 картах будут напечатаны ваши выходные данные.
2. Спасибо вам за ответ. Проблема в том, что я еще не слишком углубился в карты (что является моей следующей целью). Мне придется изучить карты, чтобы решить эту проблему. Что я хочу знать, так это то, как я могу это сделать, если я не использую карты. @Мариоалександросантини
3. Без карт вы должны создать класс MedalCounter , который содержит 2 атрибута, строку для имени и счетчик, чем создать 2 массива MedalCounter , один для стран и один для событий.
4. итак, я переберу массив победителей типа GoldMedals, а затем сделаю что-то вроде этого:
countryMedalCounter[start] = new MedalCounter(winners[i].country, 1)
я все еще не понимаю, нравится ли мне это, не потребуется ли странам с разными событиями дважды. Это сведет на нет всю цель, если только я не понял вашу идею неправильно. @Мариоалександросантини
Ответ №1:
Удалите это medalCount
поле. Ваш класс должен просто представлять входящие данные.
Затем вы хотите создать два Map<String, Long>
объекта, где ключ — это код страны или тип события, а значение — это количество для ключа.
С потоками Java 8 это довольно просто:
List<GoldMedals> allMedals = loadMedalsFromFile();
Map<String, Long> byCountry = allMedals.stream()
.collect(Collectors.groupingBy(GoldMedals::getCountry,
Collectors.counting()));
Map<String, Long> byEventType = allMedals.stream()
.collect(Collectors.groupingBy(GoldMedals::getEventType,
Collectors.counting()));
Комментарии:
1. Спасибо за потраченное время. Как я ответил другому парню, я не очень много знаю о картах. Мне нужно сделать это без maps. (я буду изучать карты для своего следующего проекта) Есть ли другой способ, которым я могу это решить?
2. Не могли бы вы мне помочь. мне действительно нужна помощь. я пытался самостоятельно последние 2 часа.
3. Я не знаю, чему вы научились, а чему нет. Они не дали бы вам задание, которое невозможно выполнить с помощью того, что вы узнали, поэтому вы должны быть в состоянии найти решение с помощью того, что вы знаете. Перечитайте свой материал еще раз. Может быть, это напомнит вам о чем-то, о чем вы не думаете.
4. все это время я кодировал самостоятельно, но получаю исключение нулевого указателя.
for (int i = 0; i < size; i ) { String name = winners[i].getCountryName(); if(!name.equals(countryArray[count].getName())) countryArray[count] = new MedalCounter(name, 1); else countryArray[count].updateCount();
5. я создал новый класс под названием MedalCounter и создал два экземпляра массива этого класса. я перебираю экземпляры GoldMedal и создаю новые экземпляры MedalCounter, если его там нет, в противном случае я просто увеличиваю счетчик. MedalCounter имеет две переменные экземпляра, называемые name и counter.
Ответ №2:
В случае, если вы не можете использовать Map. Вы можете попробовать следующий код:
—GoldMedals
public class GoldMedals {
private String country;
private String eventType;
private String event;
private int medalCount;
public GoldMedals(String name, String type, String event) {
this.country = name;
this.eventType = type;
this.event = event;
medalCount = 1;
}
/**
* @return the country
*/
public String getCountry() {
return country;
}
/**
* @param country the country to set
*/
public void setCountry(String country) {
this.country = country;
}
/**
* @return the eventType
*/
public String getEventType() {
return eventType;
}
/**
* @param eventType the eventType to set
*/
public void setEventType(String eventType) {
this.eventType = eventType;
}
/**
* @return the event
*/
public String getEvent() {
return event;
}
/**
* @param event the event to set
*/
public void setEvent(String event) {
this.event = event;
}
/**
* @return the medalCount
*/
public int getMedalCount() {
return medalCount;
}
/**
* @param medalCount the medalCount to set
*/
public void setMedalCount(int medalCount) {
this.medalCount = medalCount;
}
public boolean matchDetails(String countryName, String type){
return (country.equals(countryName) amp;amp; eventType.equals(type));
}
}
—Критерий GoldByCriteria
public class GoldByCriteria {
private String country;
private int goldMedals;
public GoldByCriteria() {}
public GoldByCriteria(String country, int goldMedals) {
this.country = country;
this.goldMedals = goldMedals;
}
/**
* @return the country
*/
public String getCountry() {
return country;
}
/**
* @param country the country to set
*/
public void setCountry(String country) {
this.country = country;
}
/**
* @return the goldMedals
*/
public int getGoldMedals() {
return goldMedals;
}
/**
* @param goldMedals the goldMedals to set
*/
public void setGoldMedals(int goldMedals) {
this.goldMedals = goldMedals;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result ((country == null) ? 0 : country.hashCode());
return resu<
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
GoldByCriteria other = (GoldByCriteria) obj;
if (country == null) {
if (other.country != null)
return false;
} else if (!country.equals(other.country))
return false;
return true;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return country " - " goldMedals;
}
}
—Использование
import java.util.ArrayList;
import java.util.List;
public class Util {
/**
* base on the criteria to get the number of gold
*
* */
public static final GoldByCriteria getGoldByCriteria(List<GoldByCriteria> list, String criteria) {
for (GoldByCriteria goldByCriteria : list) {
if(goldByCriteria.getCountry().equals(criteria)) {
return goldByCriteria;
}
}
return null;
}
/**
* group by Country
* */
public static final List<GoldByCriteria> getGoldMedalsByCountry(List<GoldMedals> goldMedals) {
List<GoldByCriteria> result = new ArrayList<GoldByCriteria>();
for (GoldMedals e : goldMedals) {
GoldByCriteria goldByCountry = Util.getGoldByCriteria(result, e.getCountry());
if( goldByCountry != null) {
goldByCountry.setGoldMedals(goldByCountry.getGoldMedals() 1);
} else {
GoldByCriteria oneGold = new GoldByCriteria();
oneGold.setCountry(e.getCountry());
oneGold.setGoldMedals(e.getMedalCount());
result.add(oneGold);
}
}
return resu<
}
/**
* group by type
* */
public static final List<GoldByCriteria> getGoldMedalsByType(List<GoldMedals> goldMedals) {
List<GoldByCriteria> result = new ArrayList<GoldByCriteria>();
for (GoldMedals e : goldMedals) {
GoldByCriteria goldByCountry = Util.getGoldByCriteria(result, e.getEventType());
if( goldByCountry != null) {
goldByCountry.setGoldMedals(goldByCountry.getGoldMedals() 1);
} else {
GoldByCriteria oneGold = new GoldByCriteria();
oneGold.setCountry(e.getEventType());
oneGold.setGoldMedals(e.getMedalCount());
result.add(oneGold);
}
}
return resu<
}
}
—Основной
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<GoldMedals> goldMedals = new ArrayList<GoldMedals>();
GoldMedals one = new GoldMedals("ITA", "Fencing", "Women's Individual Foil");
GoldMedals two = new GoldMedals("POL", "Rowing", "Men's Quadruple Sculls");
GoldMedals three = new GoldMedals("CHN", "Diving", "Men's 3m Springboard");
GoldMedals four = new GoldMedals("CHN", "Diving", "Men's Synchronised 3m Springboard");
goldMedals.add(one);
goldMedals.add(three);
goldMedals.add(two);
goldMedals.add(four);
//by country
List<GoldByCriteria> byCountries = Util.getGoldMedalsByCountry(goldMedals);
for (GoldByCriteria goldByCountry : byCountries) {
System.out.println(goldByCountry);
}
System.out.println("------------");
//by Type
List<GoldByCriteria> byType = Util.getGoldMedalsByType(goldMedals);
for (GoldByCriteria goldByType : byType) {
System.out.println(goldByType);
}
}
}
Вы должны изменить свойство «country» в GoldByCriteria на лучшее имя, например «criteria». Для быстрого кода я протестировал его со страной.
Надеюсь, это поможет.