问题
I have created a custom object called FileType
import javax.swing.ImageIcon;
class FileType
{
private int index;
private String type;
private String extension;
private String description;
ImageIcon icon;
public FileType(int index, String type, String extension, String description, String icon)
{
this.index = index;
this.type = type;
this.extension = extension;
this.description = description;
this.icon = Utils.createImageIcon(icon);
}
public int getIndex()
{
return index;
}
public String getType()
{
return type;
}
public String getExtension()
{
return extension;
}
public String getDescription()
{
return description;
}
public ImageIcon getIcon()
{
return icon;
}
}
EDIT: I also created a FileList class
import java.util.AbstractList;
import java.util.ArrayList;
public class FileList extends AbstractList
{
private ArrayList<FileType> fileList;
public FileList()
{
}
public void add(int index, String type, String extension, String description, String icon)
{
FileType data = new FileType(index, type, extension, description, icon);
if (!fileList.contains(data))
{
fileList.add(data);
}
}
@Override
public Object get(int index)
{
return fileList.toArray()[index];
}
@Override
public int size()
{
return fileList.size();
}
}
Now i want to create objects such as
- "1","html","ASCII HTML Files","images/html.png"
- "2","html","Bootstrap HTML Files","images/html.png"
Now I am lost because i want to say say something like:
list.findelementbytype ("html"); which would return FileType object, which i could then access and fetch the remaining values/attributes.
Am i on the right track or am i doing this wrong? This is for a File Chooser i am writing and i wanted to have all of the relevant data in a single object. More OO, thank you!
SOLUTION
The File Type Class which creates each data entry.
import javax.swing.ImageIcon;
class FileType
{
private int index;
private String search;
private String type;
private String extension;
private String description;
ImageIcon icon;
public FileType(int index, String search, String type, String extension, String description, String icon)
{
this.index = index;
this.search = search;
this.type = type;
this.extension = extension;
this.description = description;
this.icon = Utils.createImageIcon(icon);
}
public int getIndex()
{
return index;
}
public String getSearch()
{
return search;
}
public String getType()
{
return type;
}
public String getExtension()
{
return extension;
}
public String getDescription()
{
return description;
}
public ImageIcon getIcon()
{
return icon;
}
}
The Custom ArrayList Object which maintains the data.
import java.util.AbstractList;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class FileList extends AbstractList
{
private ArrayList<FileType> fileList;
public FileList()
{
fileList = new ArrayList<FileType>();
}
public void add(String search, String type, String extension, String description, String icon)
{
FileType data = new FileType(fileList.size(), search, type, extension, description, icon);
if (!fileList.contains(data))
{
fileList.add(data);
}
}
@Override
public Object get(int index)
{
return fileList.toArray()[index];
}
public int getIndex(String search)
{
for (FileType obj : fileList)
{
if ((obj.getSearch()).equalsIgnoreCase(search))
return obj.getIndex();
}
return -1;
}
public String getType(String search)
{
for (FileType obj : fileList)
{
if ((obj.getSearch()).equalsIgnoreCase(search))
return obj.getType();
}
return "";
}
public String getExtension(int index)
{
for (FileType obj : fileList)
{
if (obj.getIndex() == index)
return obj.getExtension();
}
return "";
}
public String getExtension(String search)
{
for (FileType obj : fileList)
{
if ((obj.getSearch()).equalsIgnoreCase(search))
return obj.getExtension();
}
return "";
}
public String getDescription(String search)
{
for (FileType obj : fileList)
{
if ((obj.getSearch()).equalsIgnoreCase(search))
return obj.getDescription();
}
return "";
}
public ImageIcon getIcon(String search)
{
for (FileType obj : fileList)
{
if ((obj.getSearch()).equalsIgnoreCase(search))
return obj.getIcon();
}
return null;
}
@Override
public int size()
{
return fileList.size();
}
}
And you would call this by:
FileList list = new FileList();
list.add("html", "random desc html", Utils.html, "ASCII HTML Files", "images/html.png");
list.add("bootstrap.html", "random desc bootstrap", Utils.bootstrap, "Bootstrap HTML Files",
"images/bootstrap.png");
list.add("xml", "random desc xml", Utils.xml, "XML Files", "images/xml.png");
list.add("json", "random desc json", Utils.json, "JSON Files", "images/json.png");
list.add("pdf", "random desc pdf", Utils.pdf, "PDF Documents", "images/pdf.png");
list.add("doc", "random desc doc", Utils.doc, "Google Documents", "images/doc.png");
These classes were created to augment JFilechooser into a more OO manner when adding custom filters, view conditions and icons.
I am sure this is not optimal when it comes to performance and a hash map would be a more ideal choice but for my purposes and time constraints this does the job i want :)
回答1:
You can use a HashMap
where you map the desired property to the object. If you want to get your objects using more than one property, you can create multiple HashMap
. The problem of this approach is that you end up with one map for each property you want to look after and you can only get object per key.
If you're looking for sorting, my suggestion is to use a TreeMap
and fiddle around with the Comparator
interface, which allows to implement comparators for multiple properties.
Edit:
Since there may be too many properties to look after and the goal is not sorting, maybe the best way is to keep using ArrayList
with the addition of Checker
classes, which check if a File
has a specified property value.
It works like the Comparator
interface (the generics here are optional):
public interface Checker<T>
{
public boolean hasProperty(T o);
}
An example of a Checker
class to find a File
by its name:
public class FileNameChecker implements Checker<File>
{
private String name;
public FileNameChecker(String name) {
this.name = name;
}
@Override
public boolean hasProperty(File f) {
return f.getName().equals(name);
}
}
And in your file system, the generic find
method:
public File find(Checker<File> checker) {
for(File f : fileList) {
if(checker.hasProperty(f))
return f;
}
return null;
}
And call it with:
find(new FileNameChecker("Filename"))
Note that you can easily modify find
to return more than one File
.
If you chose to follow this solution, I suggest you take a look at Java 8 lambdas and Stream
methods, namely filter
. These basically ease all this process.
回答2:
If you just want to get a list of all FileTypes in fileList that match a given type then this should do the trick:
public ArrayList<FileType> findElementByType(String type){
ArrayList<FileType> matchingFiles = new ArrayList<FileType>();
for (FileType file : fileList){
if (file.getType.equals(type)){
matchingFiles.add(file);
}
}
return matchingFiles;
}
Correct me if I misunderstood you
来源:https://stackoverflow.com/questions/35677855/custom-object-in-arraylist-and-searchable