#java
#java
Вопрос:
Я новичок в программировании и Java. Я пытаюсь написать свой собственный тип данных / класс коллекции, но я не совсем уверен, как это сделать.
Мне нужен класс, содержащий строку, и массив-список строк.
Обычно я бы предпочел создать тип данных, подобный этому:
public class Collection {
private int id;
private String word;
private int howMany;
private char firstChar;
public Collection (int i, String w, int h, char f){
id = i;
word = w;
howMany = h;
firstChar = f;
}
//Getters and Setters
}
Не уверен, как я могу сделать это с полем ArrayList.
Моя цель, стоящая за этим, — создать класс уникальных слов в поле string, считываемых из файлов .txt, а в поле arraylist — все имена файлов .txt, содержащие это слово.
Редактировать: основываясь на ответе Тома Андерсона и на том, что я изначально думал сделать:
public class Collection {
private int id;
private String word;
private int howMany;
private char firstChar;
private List<String> filenames;
public Collection (int i, String w, int h, char f, List<String> filenames){
id = i;
word = w;
howMany = h;
firstChar = f;
this.filenames = filenames;
}
}
Я все еще не уверен, как это использовать, поскольку я не могу просто добавить строку в параметр ArrayList при создании нового экземпляра класса my Collection. Например, это:
ArrayList<Collection> collection = new ArrayList<Collection>();
Collection newTest= new Collection("test","test");
collection.add(newTest);
Комментарии:
1. если вы пытаетесь реализовать поиск / индексирование, вы могли бы использовать lucene. Вы могли бы создать свою собственную коллекцию, либо расширив коллекцию, либо инкапсулировав ее.
2. Что это за
Collection
конструктор, который вы вызываете в своем последнем фрагменте? Вы раньше не показывали конструктор, который принимает две строки.
Ответ №1:
Прежде чем я продолжу, Collection
это неподходящее название для класса, потому что в java.util
пакете уже есть чрезвычайно популярный класс с таким именем. Я буду называть ваш класс вхождениями.
Чтобы принять ваш вопрос за чистую монету, это было бы:
public class Occurrences {
private int id;
private String word;
private int howMany;
private char firstChar;
private List<String> filenames;
public Occurrences (int i, String w, int h, char f, List<String> filenames){
id = i;
word = w;
howMany = h;
firstChar = f;
this.filenames = filenames;
}
}
Вы об этом думали? Какие у вас проблемы с этим?
Есть несколько вещей, о которых стоит упомянуть.
Во-первых, вы запросили ArrayList
, но список имен файлов имеет пару отличительных особенностей: он может содержать каждое имя файла только один раз, и порядок имен файлов не имеет значения (я предполагаю). Это означает, что на самом деле это Set
, а не a List
; класс реализации для использования здесь был бы HashSet
.
Во-вторых, вам все еще нужно создать эту коллекцию имен файлов, и, возможно, именно здесь вы зашли в тупик. Вы читаете эту информацию из файла? Если это так, допустим, у вас есть список имен файлов в строке, разделенный запятыми. Нравится:
String filenamesStr = "one.txt,two.txt,three.txt";
Самый простой способ превратить их в набор — это разделить их на массив, обернуть массив в список и использовать список для построения набора (да, действительно!):
Set<String> filenames = new HashSet<String>(Arrays.asList(filenamesStr.split(",")));
В качестве альтернативы, вы можете создавать имена файлов по мере обработки файлов. В этом случае, возможно, то, что вам следует сделать, это позволить классу Occurrences накапливать их:
public class Occurrences {
private int id;
private String word;
private int howMany;
private char firstChar;
private Set<String> filenames;
public Occurrences (int i, String w){
id = i;
word = w;
firstChar = w.charAt(0); // bonus feature!
howMany = 0;
filenames = new HashSet<String>();
}
public void addOccurrence(String filename) {
howMany;
filenames.add(filename);
}
}
Затем, когда вы индексируете свои файлы, просто вызывайте addOccurrence
каждый раз, когда видите слово.
В-третьих, как указывали другие участники ответа, Map
было бы хорошим способом организовать всю вашу вселенную слов. Вы можете использовать word в качестве ключа и либо Occurences
, либо необработанную коллекцию имен файлов в качестве значения, в зависимости от того, что вам действительно нужно.
Комментарии:
1. Это именно то, о чем я думал, но причина, по которой я не думал, что это сработает, заключается в том, что при создании нового экземпляра класса, как бы я просто добавил строку в arraylist . Простое выполнение этого не работает. Коллекция newTest= новая коллекция («test»,»тест»); collection.add(newTest);
2. Для этого есть старый трюк, когда вы хотите сразу добавить некоторые значения в коллекцию… Коллекция<Строка> newTest = новый список массивов<Строка>() {{ добавить(«тест»); добавить(«тест») }};
3. @jkschneider: Ах, старый инициализатор с двойными скобками. Это кажется довольно бесполезным его использованием, учитывая существование
Arrays.asList
; однако, это, безусловно, очень полезно для инициализации maps.4. @Tom: Помните, что Arrays.asList возвращает неизменяемый список. Позже он больше ничего не смог добавить…
5. @jkschneider: Совершенно верно. Обычно вам нужно передать этот список прямо в конструктор какой-нибудь другой коллекции.
Ответ №2:
На самом деле вам не нужен ваш собственный тип данных. Для этого и предназначен класс Map:
public void someMethod() {
Map<String, Collection<String>> filesByUniqueWord = new HashMap<String, Collection<String>>();
// inserting new entries
String uniqueWord = "hi";
List<String> filesContainingWord; // assume you have this
filesByUniqueWord.put(uniqueWord, filesContainingWord);
// deleting entries
filesByUniqueWord.remove(uniqueWord);
// getting all the files that contain some word
List<String> retrieved = filesByUniqueWord.get("hi"); // retrieved == filesContainingWord
}
Ответ №3:
Прежде всего, не вызывайте class Collection, это будет очень запутанно, поскольку Collection существует как часть библиотеки java.util.
Во-вторых, я предполагаю, что вы действительно хотите написать коллекцию, потому что вы учитесь, как это сделать, в противном случае, пожалуйста, используйте HashMap или какой-либо другой вид карты, как описано в некоторых других ответах.
Итак, предполагая, что вы действительно хотите написать коллекцию самостоятельно, я предлагаю реализовать один из стандартных интерфейсов Java. Либо java.util.Коллекция или итерируемый. Этот второй вариант был бы самым простым.
Итак, что-то вроде
класс MyCollection расширяет возможности итерации { частная строка yourString; частная строка theArray; общедоступная коллекция MyCollection(строка yourString, Строка[] theArray) { this.yourString = yourString; this.theArray = theArray } общедоступное логическое значение hasNext() { // Посмотрим, есть ли следующий элемент для возврата ... } общедоступная строка next() { // верните следующий } }
Ответ №4:
Что вам нужно, так это список строк. Теперь, увидев ваш код, я предполагаю, что мы будем использовать методы получения и установки. Поэтому, когда вы используете установщики, я думаю, что не лучшая практика присваивать значения вашим переменным внутри конструктора. Вместо этого вы можете просто создать свои объекты внутри своего конструктора
public class Collection {
private int id;
private String word;
private int howMany;
private char firstChar;
private ArrayList<String> txtFiles;
public Collection (int i, String w, int h, char f){
word=new String();
txtFiles=new ArrayList<String>();
}
}
Теперь для вашего ArrayList вы можете использовать такие методы, как
Add(String file)
Remove(String file)
Для добавления и удаления имен файлов
И для установки других переменных используйте геттеры и установщики, такие как
setId(int id)
getId()
Другая логика кодирования зависит от вас, но я думаю, что именно так вы должны проектировать свой класс