Java Selecting certain values from a set - java

I am reading from a CSV file that contains data about Hills. I can read the data from the file, and have associated column headers with 6 fields. Currently my output prints like:
### County:Argyll and Bute
[48,Deinn a'Choin,Argyll and Bute,768.2,56.281081,-4.659943, 49,Feinn a'Choin,Argyll and Bute,768.5,56.281043,-4.659924, 50,Zeinn a'Choin,Argyll and Bute,768.7,56.281034,-4.659981]
### County:Stirling
[19,Beinn Each,Stirling,813.0,56.313957,-4.262199, 11,Creag Gharbh,Stirling,637.4,56.46677,-4.221506, 7,Meall Buidhe,Stirling,719.0,56.419004,-4.308645]
### County:Aberdeen
[19,Beinn Each,Aberdeen,813.0,56.313957,-4.262199, 11,Creag Gharbh,Aberdeen,637.4,56.46677,-4.221506, 7,Meall Buidhe,Aberdeen,719.0,56.419004,-4.308645]
But I am trying to get my output like:
### County:Argyll and Bute
NameOfHill#1 Height
NameOfHill#2 Height
NameOfHill#3 Height
### County:Stirling
NameOfHill#1 Height
NameOfHill#2 Height
NameOfHill#3 Height
### County:Aberdeen
NameOfHill#1 Height
NameOfHill#2 Height
NameOfHill#3 Height
So technically what I am trying to achieve is, select 3 values from my SET which are actually inside a map and only print out the name and height.
My code currently is:
for (int i = 0; i < 3; i++) {
System.out.println("### County:" + hillsByCounty.keySet().toArray()[i]);
System.out.println(hillsByCounty.get((hillsByCounty.keySet().toArray())[i]));
}
}
I believe i have to use another for loop, and somehow select only 3 values from the Set and use ".getName" and ".getHeight" in my final print statement
I had an idea of something along the lines
Set<Hill> getHills = hillsByCounty.get((hillsByCounty.keySet().toArray())[i]);
for (int j = 0 ; j < 3 ; j++){
//write to somehow code to pull the hill in pos j in this set
System.out.println(h.getName() + " " + h.getHeight());
}
}
}
But what im not sure about is, how to get these set values. My Map value is a set because my previous method initiates like:
public static Map<String, Set<Hill>> hillsByCounty(List<Hill> hills) {

Sets don't have a get method. You could wrap it in a list e.g.
List<Hill> hills = new ArrayList<>(hillsByCounty.get((hillsByCounty.keySet().toArray())[i]));
or use a for-each loop instead. If you need to only print the first 3 you can add a counter to handle that.
int i = 0;
for (Hill h : hills) {
//Can print here with h however you like
if (++i == 3) {
break;
}
}

Looks like you need to learn about the enhanced for loop, also known as the for-each loop.
Your code should be:
int countyCount = 0;
for (Map.Entry<String, Set<Hill>> entry : hillsByCounty(readHills()).entrySet()) {
System.out.println("### County:" + entry.getKey());
int hillCount = 0;
for (Hill hill : entry.getValue()) {
System.out.println(hill.getName() + " " + hill.getHeight());
if (++hillCount == 3)
break;
}
if (++countyCount == 5)
break;
}
In Java 8, you could also use streaming:
hillsByCounty(readHills()).entrySet()
.stream()
.limit(5)
.forEach(entry -> {
System.out.println("### County:" + entry.getKey());
entry.getValue()
.stream()
.limit(3)
.map(h -> h.getName() + " " + h.getHeight())
.forEach(System.out::println);
});
See:
Javadoc - Map.entrySet()
The Java™ Tutorials - The for Statement
StackOverflow - What is the syntax of enhanced for loop in Java?
StackOverflow - Why is enhanced for loop efficient than normal for loop?

Related

Enhanced For Loop Query [duplicate]

This question already has answers here:
How does the Java 'for each' loop work?
(29 answers)
Closed 2 years ago.
could someone please explain how the enhanced for loop in the code below would look if it was represented by a standard for loop? ex for(int loop = 0; loop < ____; loop++) etc. I am trying to understand what the enhanced for loop does but want to see how it is represented in a standard for loop.
public static void main(String[] args) {
// get the list of each winning team by year
ArrayList<String> allWinners = readAndPopulateWinnersList();
int startYear = 1956;
for(String teams : allWinners) {
System.out.println(startYear++ + " : " + teams);
}
}
If you want to change your for(String teams: allWinners) to standard loop here it is:
for (int i = 0; i < allWinners.size(); i++) {
System.out.println(startYear++ + " : " + allWinners.get(i));
}
In for each you have simply form without .get(i) etc. but you don't have index either.
So If you want to print allWinners item with its index then standard for loop will be better for you. You can also use Java Streams APi: https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
so it will be allWinners.forEach(element -> System.out.println(startYear++ + " : " + element));

Cut out different elements from a string and put them into a list

Here's updated code. For those following along the question edits contains the original question.
if (0 != searchString.length()) {
for (int index = input.indexOf(searchString, 0);
index != -1;
index = input.indexOf(searchString, eagerMatching ? index + 1 : index + searchString.length())) {
occurences++;
System.out.println(occurences);
indexIN=input.indexOf(ListStringIN, occurences - 1) + ListStringIN.length();
System.out.println(indexIN);
System.out.println(ListStringIN.length());
indexOUT=input.indexOf(ListStringOUT, occurences - 1);
System.out.println(indexOUT);
Lresult.add(input.substring(indexIN, indexOUT));
System.out.println();
}
}
As you can see, I gave me out the index numbers
My code works well with only one Element
But when I write something like this: %%%%ONE++++ %%%%TWO++++
There's this exception:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: begin 16, end 7, length 23
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3410)
at java.base/java.lang.String.substring(String.java:1883)
at com.DMMS.Main.identify(Main.java:81)
And I found out that the indexIN changes in the Start of the second String but not the indexOUT
I couldn't find out why
When you look at your code you can notice: in the first loop that counts the number of occurrences, your code "knows" that it has to use that version of indexOf() that relies on offsets within the search strings.
In other words: you know that you have to search after previous "hits" when walking through your string.
But your second loop, the one that has to extract the actual things, there you are using indexOf() without that extra offset parameter. Therefore you keep "copying out" the same part repeatedly.
Thus: "simply" apply the same logic from loop 1 for loop 2!
Beyond that:
you don't need two loops for that. Counting occurrences and "copying out" the matching code ... can be done in one loop
and honestly: rewrite that first loop. This code is almost incomprehensible for human beings. A reader would have to sit down and read this 10, 20 times, and then run it in a debugger to understand what it is doing
I dit it!
Heres the code:
.........................
static String ListStringIN = "%%%%";
static String ListStringOUT = "++++";
........................
else if (input.contains(ListStringIN) && input.contains(ListStringOUT)) {
System.out.println("Identifiziere Liste...");
String searchString = ListStringIN;
int occurences = 0;
boolean eagerMatching = false;
if (0 != searchString.length()) {
for (int index = input.indexOf(searchString, 0); index != -1; index = input
.indexOf(searchString, eagerMatching ? index + 1 : index + searchString.length())) {
occurences++;
System.out.println(occurences);
indexIN=input.indexOf(ListStringIN, occurences - 1) + ListStringIN.length();
System.out.println(indexIN);
//indexOUT=input.indexOf(ListStringOUT, occurences);
//indexOUT=input.indexOf(ListStringOUT, occurences - 1);
indexOUT = input.indexOf(ListStringOUT, eagerMatching ? index + 1 : index + ListStringOUT.length());
System.out.println(indexOUT);
Lresult.add(input.substring(indexIN, indexOUT));
System.out.println();
}
}
//for (int i = 0; i <occurences; i ++) {
// Lresult.add(input.substring(input.indexOf(ListStringIN, 0) + ListStringIN.length(), input.indexOf(ListStringOUT)));
//}
result = Lresult.toString();
return result;
}
I hope this is useful for other people
#GhostCat Thanks for your advices!

Java Bubble Sort Iterates Only Twice

I'm in an intro to Java course and am just trying to get ahead of the curve with some practice, so I'm making a bubble sort program. For some reason, it only will run through the outer loop twice.
public ArrayList SortArray(ArrayList<Integer> u) {
int temp;
int spot;
for (int isOrdered = 1; isOrdered == 1;) {
for (spot = 0; spot < u.size() - 1; spot ++) {
System.out.println(u.get(spot) + " " + u.get(spot + 1) + " " + spot);
if (u.get(spot) > u.get(spot + 1)) {
temp = u.get(spot + 1);
u.set(spot + 1, u.get(spot));
u.set(spot, temp);
isOrdered = 1;
}
else {
isOrdered = 0;
}
}
}
return u;
}
As far as I can tell, what's happening is after the second iteration, it doesn't reset 'spot' to 0 so it doesn't run through the loop again. Any ideas?
Well, for starters that's an ... unusual way of using a for loop to implement a while loop. Try using a boolean for isOrdered and a while(!isOrdered) for a statement like that.
As Ted Hopp's comment said, your logic isn't quite right. What your code is doing is that it will sort ONE value in the list and once that value has "bubbled up" your flag is set to true.
You need your outer loop's condition to be that it keeps running until ALL cells are in order.
Right now your flag simply says it's sorted, when you've gone through the list, but what it needs to do is be true when it's gone through the list without performing a swap.
Try to implement that without looking, then if you can't get it (I'm assuming you're interested in doing it yourself since you're working ahead in your class) take a look at the sample here.

how to write in the database with the same persist order

I have this code I am persisting like that:
for (int i = 0; i < listofplusieurdrapage.size(); i++) {
persist(listofplusieurdrapage.get(i));
}
I have two values in
litsofplusieurdrapage => litsofplusieurdrapage.get(0) = 1
=>litsofplusieurdrapage.get(1) = 2
but when i check the database I found them in this order:
2
1
and when I add just a system.out.println to the code I have the good order
for (int i = 0; i < listofplusieurdrapage.size(); i++) {
System.out.println(" Persist : " + listofplusieurdrapage.get(i));
persist(listofplusieurdrapage.get(i));
}
1
2
do you have an explication of the problem ?
and how I can keep the good order with out adding the system.out.println to my code ?
public void persist(Object object) {
em.persist(object);
}
There is no ordering in tables, see for example this question and other links there.
If you need an order on the listofplusieurdrapage, you must specify the ordering, see for example this question.

cant sort the following tree map

for (a = 0; a < filename; a++) {
Map<Double,String> m = new HashMap<Double,String>();
String pre = "abc";
String post = ".txt";
for (int ii = 0; ii < 11; ii++) {
m.put(similarityScore[a],pre + a + post + '\n');
}
SortedSet<Double> set = new TreeSet<Double>(m.keySet());
for (Double d : set) {
System.out.println(d + " " + m.get(d));
}
}
Output :
0.5773502691896258 abc0.txt
0.5773502691896258 abc1.txt
0.5773502691896258 abc2.txt
NaN abc3.txt
0.5773502691896258 abc4.txt
NaN abc5.txt
NaN abc6.txt
NaN abc7.txt
NaN abc8.txt
0.5773502691896258 abc9.txt
NaN abc10.txt
This code should be able to sort the double values. But it displays the output on top. What happen ?
The problem is almost certainly NaN.
This is, as the name suggests, not a realy number, and behaves very strangely in terms of comparisons. Is NaN greater than, equal to, or less than 0.5773502691896258? It could be any of those results, and isn't even required to be consistent within a single execution of the program. NaN is not even equal to itself, which says something about how preconceptions of the laws of equality, and strong ordering, go out of the window when NaN is involved.
So the fix is not to use a non-numeric and expect Double.compareTo() to do what you want with it. Depending on what NaN means when returned from similarityScore(), there are several approaches you could take. If it means that it's not a match at all, you could have that method return a Double (rather than a double), return null in these cases, and then only add non-null results to the map. If these results should be displayed anyway, then perhaps you could use a result of 0.0 or -1.0, assuming that's less than any "real" similarity score. If you want something more finessed, then returning something as pure and straightforward as a primitive double is likely going to be the problem, and you may need to return your own (simple) domain class instead.
As an aside - why on earth do you create and populate a HashMap, then use a TreeSet to get the iteration order over the keys? If you simply create m as a TreeMap<Double, String> you get exactly the iteration order you want, so can just iterate overm.entrySet()`. It's clearer, more idiomatic (thus more understandable), and more efficient, so there's no reason not to do this.
for (int ii = 0; ii < 11; ii++) {
m.put(similarityScore[a],pre + a + post + '\n');
}
This puts the same value into the map 11 times - you're not referencing ii inside the loop.
for (Double d : set) {
System.out.println(d + " " + m.get(d));
}
This prints the single entry in the map.
You do the above for values 0..filename - Adding a value to the map several times, then printing it and restarting with a new map.
Map<Double,String> m = new HashMap<Double,String>();
for (a = 0; a < filename; a++) {
String pre = "abc";
String post = ".txt";
m.put(similarityScore[a],pre + a + post + '\n');
}
SortedSet<Double> set = new TreeSet<Double>(m.keySet());
for (Double d : set) {
System.out.println(d + " " + m.get(d));
}
This creates a map, populates it with values for 0..filename, then prints it sorted. You'll still have issues with NaN which isn't really sortable.
Map<Double,String> m = new TreeMap<Double,String>();
for (a = 0; a < filename; a++) {
String pre = "abc";
String post = ".txt";
m.put(similarityScore[a],pre + a + post + '\n');
}
for (Double d : m.keySet()) {
System.out.println(d + " " + m.get(d));
}
And this uses a TreeMap - No need for the intermediate Set
For any Collection to sort, the type of the value on which you are sorting should be same. And should implement comparable interface.
In your case you have NaN and Double values to sort.
Your loop means you're sorting for each filename separately. You'll need to pull the sorting out of the loop to get those values sorted. (Ooops, #Eric beat me to it.)

Categories

Resources