So I have a list of countries that I am reading from a text file and some of the countries are on there more than once. I need to put each country name into a string array without any doubles, or countries put on there twice. I tried using a for loop but could not wrap my head around the logic required for this.
Thanks in advance.
Try using a Set. A Set can contain one and not more than one of a particular instance (instance1.equals(instance2) will not be true).
Instantiate a Set like so:
Set<String> s = new HashSet<String>();
Then use a for loop to add the values.
String[] countries = {"JP", "US", "CN", "RU", "RU"}; //just make pretend these were read from a file.
for (String countryName: countries){
s.add(countryName); // RU will only be added once
}
System.out.println(s);
Outputs: [JP, US, RU, CN]
There are three different ways I can see this working:
Use a Set. This is the most efficient and easiest, and uses code that works
Each time you read in an element, iterate through the array, and see if the array already contains the element. If it does, don't add it. If you can't use Sets, this is the easiest code to write.
Read in all of the elements, sort the array. Iterate through the array, and if the current element doesn't equal the previous element, then add it to a new array. This is more efficient than #2 (O(nlog(n)) vs O(n^2)), but will require more code.
In order to check to see if a country is in the array, use an if statement. As you read in each country this checks to see if if exists in the array. If it doesn't, it adds the country to the array.
if(!Arrays.asList(yourArr).contains(country)){
yourArr[i] = country;
}
Related
I have my selenium code which pulls a list of names available in the list.
Now I want to store the same names as global for later use. Please help.
I have tried array process, it pulls only true with each line, but not the values.
List<WebElement> allText = driver.findElements(By.xpath("//*[#id='pnlLeftMenu']/table/tbody/tr/td[2]/table[2]/tbody/tr[3]/td/table/tbody/tr"));
int total = allText.size();
System.out.println(total);
for(int i=3;i<=total;i++)
{
CaselevelSigningCMs =driver.findElement(By.xpath("//*[#id='pnlLeftMenu']/table/tbody/tr/td[2]/table[2]/tbody/tr[3]/td/table/tbody/tr"+"["+i+"]"+"/td[2]")).getText();
System.out.println(CaselevelSigningCMs);
}
I should get the names like: Ranjit Nyk, Sudhanva G.... I have to verify those names in other pages in other class/method. CaselevelSigningCMs is a global variable, it pulls single item only. I need similar array defined as global so that it can pull multiple items.
CaselevelSigningCMs =driver.findElement(By.xpath("//*[#id='pnlLeftMenu']/table/tbody/tr/td[2]/table[2]/tbody/tr[3]/td/table/tbody/tr"+"["+i+"]"+"/td[2]")).getText();
See how this String CaselevelSigningCMs is defined. Just like that go for ArrayList
Lets say the string used is defined some where like
public String CaselevelSigningCMs = "";
Similarly define ArrayList
public List<String> collectedItems=new ArrayList<>();
in loop add get text of each element, something like
collectedItems.add(driver.findElement(By.xpath("//*[#id='pnlLeftMenu']/table/tbody/tr/td[2]/table[2]/tbody/tr[3]/td/table/tbody/tr"+"["+i+"]"+"/td[2]")).getText());
You can use Arraylist to store and retrieve them
ArrayList ts=new ArrayList();
store the objects in arraylist
ts.add();
You can use Stream.map() function in order to convert the list of WebElements to the List of Strings containing element text attribute in a single shot:
List<String> allText = driver.findElements(By.xpath("//*[#id='pnlLeftMenu']/table/tbody/tr/td[2]/table[2]/tbody/tr[3]/td/table/tbody/tr"))
.stream()
.map(WebElement::getText)
.collect(Collectors.toList());
allText.forEach(System.out::println);
I also don't really like your XPath expression, especially:
//* wildcard
these table[2] and tr[3]
wildcard expressions take longer time to execute and consume more resources, and your approach seems to be very dependent on DOM structure so I would recommend using XPath Axes as well as XPath Functions / Operators to make your expression as relative, robust and reliable as possible.
You can also consider using Table class of the HtmlElements framework for working with HTML tables
Let's say we have a string array like this:
{abc,abc,abc,def,def,ghi}
Is there a way to make a String array containing each possibility only once?
e.g. {abc,def,ghi}
I was thinking about iterating over an array, sorted beforehand, and checking if the previous elements equals the next one. If not add it to list and convert it to array later on if necessary.
But is there a simpler solution ?
By the way, since I am programming for android, I can't use any features of Java 8.
Simply copy the array into a Set:
Set<String> noDupes = new LinkedHashSet<>(Arrays.asList(yourArray));
By definition, Sets do not contain duplicates. You can use HashSet (or any other Set implementation) rather than LinkedHashSet, but LinkedHashSet preserves the order in which the elements first appear in the array.
Sure: iterate the array and push the values into a Set.
When using the LinkedHashSet, you even keep the initial order.
Or, without looping manually:
Set<String> = new LinkedHashSet<>(Arrays.asList(yourArray)) ;
I want to sort some number+string combination but the sorting will be based on the number from that combination. Can you suggest an optimal solution?
Say my strings are:
12 Masdf
4 Oasd
44 Twer
and so on. The sorting will be based on the numbers like 12, 4, 44 and after the sorting I have to show the full alphanumeric strings.
As the program will run on thousands of data I don't want to split the string and compare the number on each iteration. My plan is to extract the numbers and take those in an array and then sort the array. After sorting done, I want to put back the numbers with associated strings and keep those in a string array to show.
It should be done in C++. Algorithms should be applied - Insertion sort, Quick sort, Merge sort, etc.
Create a class to store the full string and the number. Make the class Comparable. Convert your list of string to list of Class. Sort the list using which sort method is relevant. Iterate the list and print the string fields.
Sorry, that was an answer for Java, since you tagged it Java. Replace/remove Comparable for whatever is good for C++.
I am going to assume these two parts are in separate variables and are not together as one string (if they were you could just store them in a list).
First consider a Map. Each 'bucket' of the map can be represented by a number. Within each of the maps buckets is a bunch of strings in a list. (Note this could also be solved with an array especially if the Integer part is always under some fixed value) The java equivalent would look like:
Map map = new HashMap<Integer,ArrayList<String>>();
For sorting on this custom collection first the integer part of the value would be searched on the map returning a list. Every item in the list will have the same starting number. So we now search the list the string part of the value (I am assuming the list is sorted so you can do whatever sort you want ie: selection/quicksort).
The advantages of this search mean that if the number is not found in the Hashmap you instantly know there is no string part for it.
Currently I'm using an ArrayList to store a list of elements, whereby I will need to insert new elements at specific positions. There is a need for me to enter elements at a position larger than the current size. For e.g:
ArrayList<String> arr = new ArrayList<String>();
arr.add(3,"hi");
Now I already know there will be an OutOfBoundsException. Is there another way or another object where I can do this while still keeping the order? This is because I have methods that finds elements based on their index. For e.g.:
ArrayList<String> arr = new ArrayList<String>();
arr.add("hi");
arr.add(0,"hello");
I would expect to find "hi" at index 1 instead of index 0 now.
So in summary, short of manually inserting null into the elements in-between, is there any way to satisfy these two requirements:
Insert elements into position larger than current size
Push existing elements to the right when I insert elements in the middle of the list
I've looked at Java ArrayList add item outside current size, as well as HashMap, but HashMap doesn't satisfy my second criteria. Any help would be greatly appreciated.
P.S. Performance is not really an issue right now.
UPDATE: There have been some questions on why I have these particular requirements, it is because I'm working on operational transformation, where I'm inserting a set of operations into, say, my list (a math formula). Each operation contains a string. As I insert/delete strings into my list, I will dynamically update the unapplied operations (if necessary) through the tracking of each operation that has already been applied. My current solution now is to use a subclass of ArrayList and override some of the methods. I would certainly like to know if there is a more elegant way of doing so though.
Your requirements are contradictory:
... I will need to insert new elements at specific positions.
There is a need for me to enter elements at a position larger than the current size.
These imply that positions are stable; i.e. that an element at a given position remains at that position.
I would expect to find "hi" at index 1 instead of index 0 now.
This states that positions are not stable under some circumstances.
You really need to make up your mind which alternative you need.
If you must have stable positions, use a TreeMap or HashMap. (A TreeMap allows you to iterate the keys in order, but at the cost of more expensive insertion and lookup ... for a large collection.) If necessary, use a "position" key type that allows you to "always" generate a new key that goes between any existing pair of keys.
If you don't have to have stable positions, use an ArrayList, and deal with the case where you have to insert beyond the end position using append.
I fail to see how it is sensible for positions to be stable if you insert beyond the end, and allow instability if you insert in the middle. (Besides, the latter is going to make the former unstable eventually ...)
even you can use TreeMap for maintaining order of keys.
First and foremost, I would say use Map instead of List. I guess your problem can be solved in better way if you use Map. But in any case if you really want to do this with Arraylist
ArrayList<String> a = new ArrayList<String>(); //Create empty list
a.addAll(Arrays.asList( new String[100])); // add n number of strings, actually null . here n is 100, but you will have to decide the ideal value of this, depending upon your requirement.
a.add(7,"hello");
a.add(2,"hi");
a.add(1,"hi2");
Use Vector class to solve this issue.
Vector vector = new Vector();
vector.setSize(100);
vector.set(98, "a");
When "setSize" is set to 100 then all 100 elements gets initialized with null values.
For those who are still dealing with this, you may do it like this.
Object[] array= new Object[10];
array[0]="1";
array[3]= "3";
array[2]="2";
array[7]="7";
List<Object> list= Arrays.asList(array);
But the thing is you need to identify the total size first, this should be just a comment but I do not have much reputation to do that.
I've been able to read a four column text file into a hashmap and get it to write to a output file. However, I need to get the second column(distinct values) into a hashset and write to the output file. I've been able to create the hashset, but it is grabbing everything and not sorting. By the way I'm new, so please take this into consideration when you answer. Thanks
Neither HashSet nor HashMap are meant to sort. They're fundamentally unsorted data structures. You should use an implementation of SortedSet, such as TreeSet.
Some guesses, related to mr Skeets answer and your apparent confusion...
Are you sure you are not inserting the whole line in the TreeSet? If you are going to use ONLY the second column, you will need to split() the strings (representing the lines) into columns - that's nothing that's done automatically.
Also, If you are actually trying to sort the whole file using the second column as key, You will need a TreeMap instead, and use the 2:nd column as key, and the whole line as data. But that won't solve the splitting, it only to keep the relation between the line and the key.
Edit: Here is some terminology for you, you might need it.
You have a Set. It's a collection of other objects - like String. You add other objects to it, and then you can fetch all objects in it by iterating through the set. Adding is done through the method add()and iterating can be done using the enhanced for loop syntax or using the iterator() method.
The set doesn't "grab" or "take" stuff; You add something to the set - in this case a String - Not an array of Strings which is written as String[]
(Its apparently possible to add array to a TreeSet (they are objects too) , but the order is not related to the contents of the String. Maybe thats what you are doing.)
String key = splittedLine[1]; // 2:nd element
"The second element of the keys" doesn't make sense at all. And what's the duplicates you're talking about. (note the correct use of apostrophes... :-)