I have a problem which requires me to create an array that will store the name of a file, and then its contents. I tried to use this, to create an Array ArrayList<String, String> fileContent = new ArrayList<String, String>(); but it calls an error, that there are an incorrect number of arguments. Whats the best way to get around this problem?
Would it be better to make two Arrays, one that stores the names, and one that stores the data in the file. Or is there another inbuilt thing inside of java that would be better to use?
create a custom class
class MyClass{
String filename;
String content;
}
// use methods as you want
then use array list for MyClass
ArrayList<MyClass> fileContent = new ArrayList<MyClass>();
If you are going to increase the properties you want to store, the answer by #while true is the correct one. If you want to store the name and the file only, you can create a HashMap like this.
HashMap<String, File> myMap = new HashMap<String, File>();
And insert elements like this:
myMap.put("filename",myFile);
Hope it helps.
Create a class that stores what you want, like this:
class Contents {
String fileName;
ArrayList<String> fileContent;
public Contents(String fileName){
this.fileName = fileName;
fileContent = new ArrayList<String>;
}
//Any Methods you need
}
and create an ArrayList like this:
ArrayList<Contents> = new ArrayList<Contents>;
This way you can store the fileName and it's contents.
The error you get is because an ArrayList can only contain one class, like String or in this example Contents.
Related
I have a CSV in this format:
"Account Name","Full Name","Customer System Name","Sales Rep"
"0x7a69","Mike Smith","0x7a69","Tim Greaves"
"0x7a69","John Taylor","0x7a69","Brian Anthony"
"Apple","Steve Jobs","apple","Anthony Michael"
"Apple","Steve Jobs","apple","Brian Anthony"
"Apple","Tim Cook","apple","Tim Greaves"
...
I would like to parse this CSV (using Java) so that it becomes:
"Account Name","Full Name","Customer System Name","Sales Rep"
"0x7a69","Mike Smith, John Taylor","0x7a69","Tim Greaves, Brian Anthony"
"Apple","Steve Jobs, Tim Cook","apple","Anthony Michael, Brian Anthony, Tim Greaves"
Essentially I just want to condense the CSV so that there is one entry per account/company name.
Here is what I have so far:
String csvFile = "something.csv";
String line = "";
String cvsSplitBy = ",";
List<String> accountList = new ArrayList<String>();
List<String> nameList = new ArrayList<String>();
List<String> systemNameList = new ArrayList<String>();
List<String> salesList = new ArrayList<String>();
try (BufferedReader br = new BufferedReader(new FileReader(csvFile)))
{
while ((line = br.readLine()) != null) {
// use comma as separator
String[] csv = line.split(cvsSplitBy);
accountList.add(csv[0]);
nameList.add(csv[1]);
systemNameList.add(csv[2]);
salesList.add(csv[3]);
}
So I was thinking of adding them all to their own lists, then looping through all of the lists and comparing the values, but I can't wrap my head around how that would work. Any tips or words of advice are much appreciated. Thanks!
By analyzing your requirements you can get a better idea of the data structures to use. Since you need to map keys (account/company) to values (name/rep) I would start with a HashMap. Since you want to condense the values to remove duplicates you'll probably want to use a Set.
I would have a Map<Key, Data> with
public class Key {
private String account;
private String companyName;
//Getters/Setters/equals/hashcode
}
public class Data {
private Key key;
private Set<String> names = new HashSet<>();
private Set<String> reps = new Hashset<>();
public void addName(String name) {
names.add(name);
}
public void addRep(String rep) {
reps.add(rep);
}
//Additional getters/setters/equals/hashcode
}
Once you have your data structures in place, you can do the following to populate the data from your CSV and output it to its own CSV (in pseudocode)
Loop each line in CSV
Build Key from account/company
Try to get data from Map
If Data not found
Create new data with Key and put key -> data mapping in map
add name and rep to data
Loop values in map
Output to CSV
Well, I probably would create a class, let's say "Account", with the attributes "accountName", "fullName", "customerSystemName", "salesRep". Then I would define an empty ArrayList of type Account and then loop over the read lines. And for every read line I just would create a new object of this class, set the corresponding attributes and add the object to the list. But before creating the object I would iterate overe the already existing objects in the list to see whether there is one which already has this company name - and if this is the case, then, instead of creating the new object, just reset the salesRep attribute of the old one by adding the new value, separated by comma.
I hope this helps :)
I have a HashSet of Strings in the format: something_something_name="value"
Set<String> name= new HashSet<String>();
Farther down in my code I want to check if a String "name" is included in the HashSet. In this little example, if I'm checking to see if "name" is a substring of any of the values in the HashSet, I'd like it to return true.
I know that .contains() won't work since that works using .equals(). Any suggestions on the best way to handle this would be great.
With your existing data structure, the only way is to iterate over all entries checking each one in turn.
If that's not good enough, you'll need a different data structure.
You can build a map (name -> strings) as follows:
Map<String, List<String>> name_2_keys = new HashMap<>();
for (String name : names) {
String[] parts = key.split("_");
List<String> keys = name_2_keys.get(parts[2]);
if (keys == null) {
keys = new ArrayList<>();
}
keys.add(name);
name_2_keys.put(parts[2], keys);
}
Then retrieve all the strings containing the name name:
List<String> keys = name_2_keys.get(name)
You can keep another map where name is the key and something_something_name is the value.
Thus, you would be able to move from name -> something_something_name -> value. If you want a single interface, you can write a wrapper class around these two maps, exposing the functionality you want.
I posted a MapFilter class here a while ago.
You could use it like:
MapFilter<String> something = new MapFilter<String>(yourMap, "something_");
MapFilter<String> something_something = new MapFilter<String>(something, "something_");
You will need to make your container into a Map first.
This would only be worthwhile doing if you look for the substrings many times.
I am writing an interpreter program and I am stuck at the moment with this.
There is a Map for Integers and MJObjects:
private Map<Integer, MJObject> objectHeap;
objectHeap = new HashMap<Integer, MJObject>();
MJObject class looks like this:
MJObject(SymbolTable symTab, String className)
I create a new MJObject and store it inside a Map with a reference integer.
public Integer allocClassInstance(String className)
MJObject object = new MJObject(symTab, className);
objectHeap.put(nextFree, object);
Then from another method using just the reference of the MJObject, I need to retrieve the className inside the MJObject. How can I do that? Thank you for your help.
Then from another method using just the reference of the MJObject, I need to retrieve the className inside the MJObject. How can I do that?
If you've already got the MJObject then the map is irrelevant. Assuming the MJObject makes the class name it was constructed with accessible somehow, you just want something like:
String className = mjObject.getClassName();
If you're actually trying to get the key in the map which is associated with that MJObject, you'd have to iterate through the map - or potentially create a second map with the reverse mapping (MJObject to Integer).
I have a method that read from database and get some string there. According what I get I will override that string for another that I already know. For example:
str → string
bin → binary
and so on..
My question is, what is the best practice for doing this? Of course I already thought about if's...
if (str.equals("str"))
str = "string";
A file that have this things pre-defined, a multi-dimensional array, etc.. But this all seems a quite newbie, so what do you recommend? What is the best way?
Use a Map:
// create a map that maps abbreviated strings to their replacement text
Map<String, String> abbreviationMap = new HashMap<String, String>();
// populate the map with some values
abbreviationMap.put("str", "string");
abbreviationMap.put("bin", "binary");
abbreviationMap.put("txt", "text");
// get a string from the database and replace it with the value from the map
String fromDB = // get string from database
String fullText = abbreviationMap.get(fromDB);
You can read more about Maps here.
You could use a map, for example:
Map<String, String> map = new HashMap<String, String>();
map.put("str", "string");
map.put("bin", "binary");
// ...
String input = ...;
String output = map.get(input); // this could be null, if it doesn't exist in the map
Map is a good option as people have suggested. The other option which I normally consider in this scenario is Enum. It gives you an additional capability of adding behavior for a combination.
I am using a class where I am taking input as the file name and the file location. I have a pre defined file names, so I will match the predefined file names with the file name that I received and then store the values accordingly. Please look at the code below
//Set of storage maps and tables
public class storage
{
//Storage set
public static Set<Integer> tiger = new HashSet<Integer>();
//Storage set
public static Set<Integer> lion = new HashSet<Integer>();
//This is the table used for storing the browser customer count
public static Table<String,String,Integer> elephant = HashBasedTable.create();
//Storage map
public static Map<String, String> monkey = new HashMap<String, String>();
public static void storeDataDirector(String fileLocation,String fileName) throws Exception
{
if (fileName = monkey)
**update the "monkey map"**
}
This is my problem, also I have lot of maps and tables to be used so I wouldn't be able to use multiple if conditions and then check and update the same.
What I would like to know is the below
As I have said earlier, The file name that I am sending to the program which is "String filename" has the same name of the "Map monkey" but the former is a String and the latter is the map. I would like to know if I will be able to use the string variable as a reference to the map instance as both of them have the same name . This will highly avoid the if conditions that I am using in the program and thus I would like to possible solution for this ... Anything related to type caseting ort
You need to have another Map - whose key is a String and value is a Map. Something like Map<String,Map> allMaps = new HashMap<String,Map>()
Once you have this map , populate it with all your filenames and the corresponding maps monkey.
allMaps .put("monkey", monkey)
If a string filename corresponds to not a map but to a set , then you need to declare something more general Map<String,Object> allMaps = new HashMap<String,Object>(). Ofcourse this means you need to cast the value to its particular type before you can do any meaningful thing with it.
Then , to use this map , use your filename argument
Map monkeyAgain = allMaps.get(filename)
You can use reflection:
Storage.class.getField(fileName).get(null)
You will still have to cast the returned object. I do not think this the right approach.
The idea is to relate them in a Map, and use the file name as a key for example
Map<String, Map<String, String>>
// file store structure
If you need a generic solution, you could solve this by implementing an abstraction of your store structure, by implementing an interface similar to this one:
// T is the store type and U is the original type (String from file for instance...)
public interface StoreUnit<T, U> {
void update(U record);
List<T> list();
}
so you will have an implementation for each case (Set, Map, Table ...) and will relate it in a map using the file name as key.
monkeyFileName => MapStoreUnit<Entry<String,String>,String>
tigerFileName => SetStoreUnit<Integer, String>
elephantFileName => TableStoreUnit<Entry<Entry<String,String>,String>,String> // not sure if for Table there is something better than Entry ;)
When you wanna update some store you perform a get over the map using the file name as key, and invoking update method implemented with the record (that could be an String, complex Object) and so on. When you need to read something from there you could use the list method.