All the split command I have seen split (for example) a CSV file into the 1 array.
e.g.
cat,feline,house
dog,canine,house
monkey,primate,zoo
Into
array[0] = cat
array[1] = feline
array[2] = house
Is there a way to split them into separate arrays per line so it would be more like (so you can keep specific attributes in the same lines of the csv:
into
animal[0] = cat
species[0] = feline
lives[0] = house
A much better approach is to create a POJO:
public class MyAnimal {
private String animal;
private String family;
private String place;
private String country;
// getters and setters...
}
Then you can use a parser or read the file line by line and convert it to a List<MyAnimal>
Using array to hold object data is not the way to do it.
You can try this
BufferedReader br = new BufferedReader(new FileReader("D:\\sample.txt"));
String st = null;
String[] animal = new String[10];
String[] species = new String[10];
String[] lives = new String[10];
int j = 0;
while ((st = br.readLine()) != null) {
String[] str = st.split(",");
for (int i = 0; i < str.length; i++) {
animal[j] = str[0];
species[j] = str[1];
lives[j] = str[2];
}
j++;
}
But it is better to use ArrayList here.
Such an abstract split does not exist as a default as far as I know.
The basic way you would go about achieving this, would be first to do the regular split as you said, which gave the result.
array[0] = cat
array[1] = feline
array[2] = house
Then you could loop through the array and check for the different things.
ArrayList<String> animals = new ArrayList<String>();
ArrayList<String> lives = new ArrayList<String>();
for (int i = 0; i < array.length; i++) {
if (array[i].equalsIgnoreCase("cat") || array[i].equalsIgnoreCase("dog")) {
animals.add(array[i]);
}
else if (array[i].equalsIgnoreCase("house") || array[i].equalsIgnoreCase("zoo")) {
lives.add(array[i]);
}
}
Then you would of course do that for all the cases you have. It's a pretty complex way to do it, though really simple to understand.
Edit
To achive what you asked in the comments, you could do something like this.
ArrayList<String> animals = new ArrayList<String>();
ArrayList<String> lives = new ArrayList<String>();
for (int i = 0; i < array.length; i += 5) {
animals.add(array[i]);
lives.add(array[i + 1]);
}
Then the + 1 for selecting the index in the array would of course depend on the index from the splitted String.
String.split works like separating items by the delimiters, it doesn't know what a item is. If you want to associate items on some pattern to be recognized when parsing the string, you should supply those patterns to the categories the items should be associated to. If it's a CSV and you want to get the table data, then you should supply the metadata described the column names and dimensions. Without this metadata it's impossible to parse your document correctly.
Related
I'm creating a java scraping program using selenium and inserting the data into a database. I'm actively looking to improve my skillset but I don't find instructional videos too helpful since I lose interest, but I really enjoy learning through doing. This code below works as needed, but it looks really really ugly and I feel there must be a better/cleaner solution. For reference it builds a comma separated string with data such as "Value1", or "Value1, Value2", etc depending on the keyword count. My original logic was outputting ", Value1, Value2" which is why I added the "if (x ==0)" logic. I have a lot of methods that are just sloppy like this, so any pointers for improving my code is appreciated, thanks!
ArrayList<String> keywords = new ArrayList<String>();
keywords = keywordChecker(title);
for (int x = 0; x < keywords.size(); x++) {
String list = keywords.get(x);
if (x == 0) {
keywordListBuilder = list;
} else if (x > 0) {
keywordListBuilder = keywordListBuilder + ", " + list;
}
}
keywordValues.add(keywordListBuilder);
public ArrayList<String> keywordChecker(String title) {
ArrayList<String> keywordList = new ArrayList<String>();
String keyword1 = "";
String keyword2 = "";
String keyword3 = "";
String[] keywordTextCombinations = { "Value1", "Value2", "Value3", [imagine a list of 20 items]};
for (int i = 0; i < keywordTextCombinations.length; i++) {
if (title.toLowerCase().contains(keywordTextCombinations[i].toLowerCase())) {
keyword1 = keywordTextCombinations[i];
keywordList.add(keyword1);
break;
}
}
for (int i = 0; i < keywordTextCombinations.length; i++) {
if (title.toLowerCase().contains(keywordTextCombinations[i].toLowerCase())
&& !keywordTextCombinations[i].toLowerCase().equals(keyword1.toLowerCase())
&& !keywordTextCombinations[i].toLowerCase().equals(keyword2.toLowerCase())) {
keyword2 = keywordTextCombinations[i];
keywordList.add(keyword2);
break;
}
}
for (int i = 0; i < keywordTextCombinations.length; i++) {
if (title.toLowerCase().contains(keywordTextCombinations[i].toLowerCase())
&& !keywordTextCombinations[i].toLowerCase().equals(keyword1.toLowerCase())
&& !keywordTextCombinations[i].toLowerCase().equals(keyword2.toLowerCase())) {
keyword3 = keywordTextCombinations[i];
keywordList.add(keyword3);
break;
}
}
return keywordList;
}
ArrayList<String> keywords = new ArrayList<String>();
keywords = keywordChecker(title);
This will:
Create a new variable, named keywords, that can point at arraylists.
Makes a new arraylist object.
Assigns the reference to this newly created object to the keywords variable.
Then tosses that reference away and makes that created object instant garbage, as you then immediately assign some other reference to it.
In other words, that new ArrayList<String>(); does nothing whatsoever but waste time and space. Get rid of it. Let's also be like other java coders and use the most general type that we're interested in. For beginners, that basically means, 'the variable should be of type List, not ArrayList. It's good to write code in similar style to other java coders; makes it easier to read their code and it makes it easier for them to read your code.
List<String> keywords = keywordChecker(title);
for (int x = 0; x < keywords.size(); x++) {
String list = keywords.get(x);
if (x == 0) {
keywordListBuilder = list;
} else if (x > 0) {
keywordListBuilder = keywordListBuilder + ", " + list;
}
}
keywordValues.add(keywordListBuilder);
You're getting a single keyword and you call this list? Names are important. When they lie, your code becomes unreadable.
You're turning a list of strings into a single string with all the values, separated by a comma. That sounds like a common job. When something sounds common enough, search the web. You'll usually find that there's a one-liner. So it is here:
keywordValues.add(String.join(", ", keywords));
Oof, that's way less code.
The keywordChecker method
It helps to document code, especially when asking for help. Evidently, this method is to scan the provided title variable, and search for any of a list of keywords, then it is to return each matching keyword. However, you've limited to return at most 3. I assume you didn't want that. But if you do, I'll show you how, with a one-liner of course.
String keyword1 = "";
String keyword2 = "";
String keyword3 = "";
When you start naming variables like this, stop. There's no way that's correct. Think for a moment. You're already using them, you know how to do this properly: Lists. Once you use a list, this becomes near trivial. Also, method names should generally be a verb; common java style. Let's also make constants, well, constant. Let's also avoid arrays, they are unwieldy and annoying.
private static final List<String> KEYWORDS = List.of("Value1", "Value2", "Value3", [imagine a list of 20 items]);
public List<String> findMatchingKeywords(String title) {
var out = new ArrayList<String>();
String lowercased = title.toLowerCase();
for (String keyword : KEYWORDS) {
if (lowercased.contains(keyword.toLowerCase()) out.add(keyword);
}
return out;
}
That eliminated a ton of lines, that's nice. If you want to return no more than 3 keywords at most... all you need to do is abort looping when you're 'full'. As last line within the for loop:
if (out.length() == 3) break;
Putting it all together:
keywordValues.add(String.join(", ", findMatchingKeywords(title)));
...
private static final List<String> KEYWORDS = List.of("Value1", "Value2", "Value3", [imagine a list of 20 items]);
public List<String> findMatchingKeywords(String title) {
var out = new ArrayList<String>();
String lowercased = title.toLowerCase();
for (String keyword : KEYWORDS) {
if (lowercased.contains(keyword.toLowerCase()) {
out.add(keyword);
if (out.length() == 3) break;
}
}
return out;
}
You can try to do everything in one for loop. Also, I recommend that you use a HashSet since you are comparing elements. A HashSet cannot contain duplicate elements, so if you try to add an element that already exists it doesn't do it and it returns false (Yes, the add function in HashSet returns a boolean).
Hello everyone i am trying to remove an name that the user has put in from an String Array, i am new to programming and i have tried this but it doesn't work. Can someone help me or tell me what i am doing wrong?
String [] myName = {"Testname","Charel","melissa","Kelly"};
removeName(myName);
public void removeName(String[] names )
{
Scanner sc = new Scanner(System.in);
String name = "";
name = sc.nextLine();
for (int i = 0; i < names.length; i++) {
name = names[i-1];
}
}
How can i do this?
You probably need to use Lists for this. Your list will be a list of String, and use remove() method to do this.
An array's length is fixed and can't be changed this way.
Useful Link : Removing items from a list
First off, an array does not change size after it is initialized, the only way to change the size of an array is to replace it with a new array! So in order to not end up with a double entry or an empty field, you would need to make a new array that is one size shorter, and write the names you want to keep into that.
An array might be ill-suited for your purposes, so consider using a list or an ArrayList. A list can be resized, so removing an element will automatically shorten the list. I recommend you look into that.
Lastly, you currently aren't even comparing your input to your fields. Replace name = names[i-1]; with something along the lines of
if(name.equals(names[i]))
//TODO: Remove from list
See here for more details about String.equals()!
Also, keep in mind that the user input might not match any name at all, so prepare for that case as well!
To remove an element from an array in Java, you need to create a new array and copy over all the elements you want to keep. That is because Java arrays are fixed-size.
For example, to remove an element at a particular index, you could do it like this:
public static String[] remove(String[] array, int index) {
String[] result = new String[array.length - 1];
System.arraycopy(array, 0, result, 0, index);
System.arraycopy(array, index + 1, result, index, result.length - index);
return result;
}
You would then remove melissa from your array as follows:
String[] names = { "Testname", "Charel", "Melissa", "Kelly" };
names = remove(names, 2);
System.out.println(Arrays.toString(names));
Output
[Testname, Charel, Kelly]
Of course, it would be much easier to do it using a List:
List<String> names = new ArrayList<>(Arrays.asList("Testname", "Charel", "Melissa", "Kelly"));
names.remove(2);
System.out.println(names);
Or:
List<String> names = new ArrayList<>(Arrays.asList("Testname", "Charel", "Melissa", "Kelly"));
names.remove("Melissa");
System.out.println(names);
Output of both is the same as above.
There are some simple methods using java api provide by jdk, for example:
String [] myName = {"Testname","Charel","melissa","Kelly"};
List<String> container = new ArrayList(Arrays.asList(myName));
container.remove("Charel");
String[] result = new String[myName.length - 1];
container.toArray(result);
Alternatively you can also use this to convert array to list,
Collections.addAll(container, myName);
String [] myName = {"Testname","Charel","melissa","Kelly"};
removeName(myName);
public void removeName(String[] names )
{
Scanner sc = new Scanner(System.in);
String name = sc.nextLine();
for (int i = 0; i < names.length; i++) {
if(names[i]==name)
{
for(int j=i;j<names.length-1;j++)
{
names[j]=names[j+1];
}
}
}
}
I am trying to create an array of objects with a MAX_N 6 object into this array, then create another array within an else statement to fit the rest of the array objects.
I would like to name the new array
sbag1
sbag2
etc
here is my code:
public static ShoppingBag[] packIntoBags(GroceryItem[] goods) {
ShoppingBag newBag = new ShoppingBag();
GroceryItem tmpObject = null;
int index = 0;
String bag = "newBag";
String bagNum = bag + index;
for (int i = 0; i < MAXNBAG; i++)
if (newBag.numItems() < MAX_NUM_ITEMS) {
for (int k = 0; i < MAX_NUM_ITEMS; i++) {
tmpObject = goods[i];
newBag.addToBag(tmpObject);
}
}
else {
ShoppingBag newBag1 = new ShoppingBag();
}
}
You will not be able to dynamically create new variables in java.
When I look at the signature of your method you don't need to return multiple variables, only an array of ShoppingBags.
You should create a variable of type List<ShoppingBag>:
List<ShoppingBag> shoppingsBags=new ArrayList<>();
each time you need a new ShoppingBag:
bag=new ShoppingBag();
shoppingBags.add(bag);
at the end convert this list to an array:
return shoppingBags.toArray(new ShoppingBag[0]);
Java is a statically compiled language. In general, it is not possible, or to be precise: not helpful to use "dynamic" names for variables.
What you could do instead: use a Map, or even more simple: an array of arrays to hold your data.
I have sorted an array of objects into descending order based on one of their variables. I now need to take the first two values of this array and place them in a new String array. What I have so far is below, but Im obviously making a stupid mistake somewhere.
public String[] teamsToProgress()
{
Arrays.sort(teams);
String[] teamsToProgress = new String[2];
for (int i=0; i<2 ; i++)
{
teams[i] = teamsToProgress[i];
}
}
You try to assign String to a Team field (here: teams[i] = teamsToProgress[i];). You'll have to convert (not casting) the String to a Team instance before assigning.
If your just looking for a logical error, here it is:
teams[i] = teamsToProgress[i]; should be replaced to teamsToProgress[i] = teams[i];
I'm not getting into the details of the syntax involved. But I guess this is what you wanted based on your question.
teams[i] = teamsToProgress[i]; should be reversed, this make no sense. You're also missing a return statement.
public String[] teamsToProgress()
{
Arrays.sort(teams);
String[] teamsToProgress = new String[2];
for (int i=0; i<2 ; i++)
{
teamsToProgress[i] = teams[i]; //.getSomething() ?
}
return teamsToProgress;
}
your question is not clear enough as we still need to learn about Team object structure. but I'm guessing you are looking after something like this.
public String[] teamsToProgress(Team[] teams) //pass your sorted teams array as a param.
{
String[] teamsToProgress = new String[2];
for (int i=0; i<2; i++)
{
teamsToProgress[i] = String.valueOf(teams[i]); //convert teams[i] to string
}
return teamsToProgress;// you need to return an array
}
I have a collection of Ingredient objects for which I'd like get all their names (via getName()) and join them into a comma-delimited string. Currently my code looks like this:
public static String getIngredientList(Collection<Ingredient> ingredients) {
final Iterator<Ingredient> iterator = ingredients.iterator();
final String[] names = new String[ingredients.size()];
for (int i = 0; iterator.hasNext(); i++) {
names[i] = iterator.next().getName();
}
return TextUtils.join(", ", names);
}
I'm wondering if there's a more concise way to collect all the names into a String[] object. If this were Ruby, for example, it'd be easy to pull off a short one-liner to do exactly what I need:
ingredients.map(&:name).join(', ')
Using Eclipse Collections you can write the following using JDK 5 - 7:
MutableList<Ingredient> ingredients =
Lists.mutable.with(
new Ingredient("Flour"),
new Ingredient("Sugar"),
new Ingredient("Eggs"),
new Ingredient("Milk"));
MutableList<String> ingredientNames = ingredients.collect(new Function<Ingredient, String>()
{
public String valueOf(Ingredient ingredient)
{
return ingredient.getName();
}
});
String delimitedNames = ingredientNames.makeString(", ");
Assert.assertEquals("Flour, Sugar, Eggs, Milk", delimitedNames);
Using Java 8 with support for lambdas and method references you can compress it down to the following:
MutableList<Ingredient> ingredients =
Lists.mutable.with(
new Ingredient("Flour"),
new Ingredient("Sugar"),
new Ingredient("Eggs"),
new Ingredient("Milk"));
String delimitedNames =
ingredients.collect(Ingredient::getName).makeString(", ");
Assert.assertEquals("Flour, Sugar, Eggs, Milk", delimitedNames);
In this example, using the overloaded form of makeString() without parameters will result in the same string, as makeString() calls makeString(“, “).
String delimitedNames =
ingredients.collect(Ingredient::getName).makeString();
Assert.assertEquals("Flour, Sugar, Eggs, Milk", delimitedNames);
Note: I am a committer for Eclipse Collections.
Why don't you use a StringBuilder in the first place?
The relevant part of the code:
StringBuilder b = new StringBuilder();
for(Ingredient ingredient: ingredients) {
b.append(ingredient.getName() + ", ");
}
return b.toString();
Of course you have to remove the last ", " appended which can be done with using the substring method or not appending the last one.
StringBuilder result = new StringBuilder();
for(String string : collectionOfStrings) {
result.append(string);
result.append(",");
}
return result.length() > 0 ? result.substring(0, result.length() - 1): "";
see the duplicate post:
The most sophisticated way for creating comma-separated Strings from a Collection/Array/List?