Any way to improve this String comparison with Java? - java

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class NNNTest {
private String SkillNeed="Java;C++;C";
private String SkillHave="SQL:8;Java:9;C++:5;C:9;PHP:5";
public boolean CheckAvailable(){
int flag=0;
int k;
String [] snar=SkillNeed.split(";");
String [] shandlevel=SkillHave.split(";");
for(int i=0;i<snar.length;i++){
for(k=0,flag=0;k<shandlevel.length;k++){
if(shandlevel[k].split(":")[0].equals(snar[i])){
System.out.println(shandlevel[k].split(":")[0]);
flag=1;
}
}
if(flag==0){
break;
}
}
if(flag==1){
System.out.println("YES");
return true;
}
else{
System.out.println("NO");
return false;
}
}
public static void main(String[] args) {
NNNTest n=new NNNTest();
n.CheckAvailable();
}
}
The method check if you have enough skills to acquire the job.
SkillNeed is a String that with form "skill;skill;skill....."
SkillHave is the skills and level you have and with form "skill:level;skill:level;...."
These are the codes that I typed,but I think it's pretty long and boring,do you have any other way to improve the method?Something like skipping the loop or Array or using java given methods.

Simply way with java-8:
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
public class NNNTest {
private static String skillNeed = "Java;C++;C"; //the skills the job need
private static String skillHave = "SQL:8;Java:9;C++:5;C:9;PHP:5"; //skill and level you have
public static boolean checkAvailable() { //if all the job needed skills match the skills you have
return Arrays.stream(skillHave.split(";")).map(s -> s.split(":")[0]).collect(Collectors.toSet()).containsAll(Arrays.asList(skillNeed.split(";")));
}
public static void main(String[] args) {
System.out.println(checkAvailable());
}
}
Edited for explanation:
Collect al skillHave in a Set (without the number).
Check if the Set of skillHave contains all elements of a given collection.
Collect all SkillNeed in another Set and pass it as parameter for previous step.

Another Java 8 Solution..
It basically iterates through all required skills and makes sure, using the allMatch() function, that each skill is contained in the givenSkills-String. Keep in mind, that you have to check for ":" aswell, otherwise "C" would also match "C++". This also makes sure, that it exactly matches the skill, since the skill is either at the beginning, or it is enclosed by ; and :.
public static boolean checkForRequiredSkills(String requiredSkills, String givenSkills)
{
return Arrays.stream(requiredSkills.split(";")).allMatch(skill -> givenSkills.startsWith(skill + ":") || givenSkills.contains(";" + skill + ":"));
}
A similar solution in earlier java versions could be looking like this
public boolean checkAvailable()
{
for (String skill : skillNeed.split(";"))
{
if (!skillNeed.startsWith(skill + ":") && !skillHave.contains(";" + skill + ":"))
return false;
}
return true;
}
Also the preferred idiom, to iterate over an Array or List is using a for-each loop..
for(String str : stringArray)
doSomething(str);

Related

Making a Free Response Quiz from text file

I'm new to java and I working on this project to answer questions from a text file in random order. NO MULTIPLE CHOICE In the end it has count how many questions you got wrong. In the code you have to make a class called QAndA, with "a" as anwser and "q" as question in the data fields. Then at the end of that class make a toString() method to return "a" and "q". I will show that below.
class QAndA{
String q; //question
String a; //answer
QAndA(String q, String a){
this.q = q;
this.a = a;
}
public String getQ(){
return q;
}
public String getA(){
Scanner input = new Scanner(System.in);
System.out.println("Enter your answer: ");
a = input.next();
return a;
}
#Override
public String toString(){
return q;
}
}
All there is to fix is just taking a question one at a time from the file and inputting the answer to see if its right. Also we have to use an ArrayList class with the QAndA objects. Example: ArrayList theNameoftheArray = new ArrayList();
Here is what the text file is suppose to look like:
Q: How do you call a general binary relationship that describes an activity between two classes?
A: association
Q: Defining multiple methods with the same name as long as their parameter lists are different is called?
A: overloading
Q: Write a statement that assigns the value true to the first element of the array butterfly.
A: butterfly[0] = true;
Q: When the return type of a method is an array, it actually returns?
A: a reference to the array
Q: True or false (T/F)? Constructors have the return type void.
A: F
Any help will be appreciated! Thank You!
Actually stackoverflow shouldn't be a place to ask for full solutions for programs - anyway as you are new here -> here is my mini solution (without appropriate error handling!)
package at.mad.max;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class QandAMain {
static class QAndA {
String q; // question
String a; // answer
public QAndA(String q, String a) {
this.q = q;
this.a = a;
}
public String getQ() {
return q;
}
public String getA() {
return a;
}
}
public static String readAnswerFromConsole() {
System.out.println("Enter your answer: ");
return new Scanner(System.in).next();
}
public static List<String> readFileFromResourceLineByLine(String fileName) throws IOException, URISyntaxException {
URL resource = QandAMain.class.getClassLoader().getResource(fileName);
if (resource != null) {
return Files.readAllLines(new File(resource.toURI()).toPath(), StandardCharsets.UTF_8);
}
return Collections.emptyList();
}
public static void main(String[] args) throws IOException, URISyntaxException {
Pattern pattern = Pattern.compile("^Q: (.+[^A:]) A: (.+)");
List<String> lines = readFileFromResourceLineByLine("q_and_a.txt");
List<QAndA> qAndAs = new ArrayList<QandAMain.QAndA>();
lines.forEach(l -> {
Matcher m = pattern.matcher(l);
if (m.find()) {
qAndAs.add(new QAndA(m.group(1), m.group(2)));
}
});
Collections.shuffle(qAndAs);
for (int i = 0; i < qAndAs.size(); i++) {
QAndA qa = qAndAs.get(i);
System.out.println("-- Question ("+(i+1)+" of "+qAndAs.size()+"): --\n"+qa.getQ());
String userAnswer = readAnswerFromConsole();
if (userAnswer != null && qa.getA().trim().equalsIgnoreCase(userAnswer.trim())) {
System.out.println("Shiiish\n");
} else {
System.out.println("Nope\n");
}
}
System.out.println("Done!");
}
}
You need to place a file with the above mentioned questions and answers in the resource path - in my example I called the file "q_and_a.txt".
You get following output:
-- Question (1 of 5): --
True or false (T/F)? Constructors have the return type void.
Enter your answer:
F
Shiiish
-- Question (2 of 5): --
How do you call a general binary relationship that describes an activity between two classes?
Enter your answer:
association
Shiiish
-- Question (3 of 5): --
When the return type of a method is an array, it actually returns?
Enter your answer:
a pointer
Nope
...
...

Compare Arraylist of Strings with String

I tried Arrays.asList().contains(string) to compare array items with string but return is false every time even emailid matches .
This is my array:
List<String> arraySE = new ArrayList<String>();
if(Arrays.asList(arraySE).contains(c.getString(c.getColumnIndex(KEY_EMAIL)))){
user.setSelected(true);
} else{
user.setSelected(isSelect);
}
Sample ARRAY:
[user1#gmail.com, user2#gmail.com, user3#gmail.com]
NO ERROR, returning false
A primitive example that works correctly:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> arrayList = new ArrayList<>();
arrayList.add("Hello");
arrayList.add("Hola");
arrayList.add("Hallo");
boolean contains = arrayList.contains("Hello");
System.out.println(contains);
}
}
I would recommend that you debug through your code and especially see what c.getString(c.getColumnIndex(KEY_EMAIL)) returns.
boolean isThere = Arrays.asList(yourArray).contains("test");
if(isThere){
}
else{
}
At first, your list in your example is empty.
Sencodly, you don't need to use Arrays.asList(arraySE), because it is already a list.
You can simply use the contains function to check:
List<String> arraySE = Arrays.asList("user1#gmail.com", "user2#gmail.com", "user3#gmail.com");
if (arraySE.contains("user1#gmail.com")) {
System.out.println("true");
} else {
System.out.println("false");
}
You already have a list of strings, call contains on it. It will work if a match is found.
Why it is failing now is basically when you are calling asList the returned list is not a list of strings, so equals method works differently in that case.
import java.util.ArrayList;
import java.util.Arrays;
public class Test2 {
public static void main(String[] args) {
String str[] = {"A","B","C","D"};
ArrayList a = new ArrayList(Arrays.asList(str));
System.out.println(a.contains("A"));
}
}

Junit: assert that a list contains at least one property that matches some condition

I have a method that will return a list of objects of type MyClass. MyClass has many properties, but I care about type and count. I want to write a test that asserts that the returned list contains at least one element that matches a certain condition. For instance, I want at least one element in the list of type "Foo" and count 1.
I'm trying to figure out how to do this without literally looping over the returned list and checking each element individually, breaking if I find one that passes, like:
boolean passes = false;
for (MyClass obj:objects){
if (obj.getName() == "Foo" && obj.getCount() == 1){
passes = true;
}
}
assertTrue(passes);
I really don't like this structure. I'm wondering if there's a better way to do it using assertThat and some Matcher.
with hamcrest imports
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
you can test with
assertThat(foos, hasItem(allOf(
hasProperty("name", is("foo")),
hasProperty("count", is(1))
)));
assertTrue(objects.stream().anyMatch(obj ->
obj.getName() == "Foo" && obj.getCount() == 1
));
Or more likely:
assertTrue(objects.stream().anyMatch(obj ->
obj.getName().equals("Foo") && obj.getCount() == 1
));
I don't know if it's worth using Hamcrest for this but it's good to know it's out there.
public class TestClass {
String name;
int count;
public TestClass(String name, int count) {
this.name = name;
this.count = count;
}
public String getName() {
return name;
}
public int getCount() {
return count;
}
}
#org.junit.Test
public void testApp() {
List<TestClass> moo = new ArrayList<>();
moo.add(new TestClass("test", 1));
moo.add(new TestClass("test2", 2));
MatcherAssert.assertThat(moo,
Matchers.hasItem(Matchers.both(Matchers.<TestClass>hasProperty("name", Matchers.is("test")))
.and(Matchers.<TestClass>hasProperty("count", Matchers.is(1)))));
}

Search for an object in arrayList Java

package generics;
import java.util.ArrayList;
import java.util.List;
public class Generics {
private static List <Box> newlist = new ArrayList<>();
public static void main(String[] args) {
newlist.add(new Box("charlie",30));
newlist.add(new Box("max",29));
newlist.add(new Box("john",22));
// Testing method find -- Start
find ("max",29);
//Testing method find2 -- Start
Box <String,Integer> search = new Box("max",29);
find2(search);
}
public static void find (String parameter, Integer parameter1){
for (Box e : newlist){
if(e.getName() != null && e.getMoney() !=null
&& e.getName().equals(parameter)
&& e.getMoney().equals(parameter1)){
System.out.println("found on position " + newlist.indexOf(e));
break;
}
}
}
public static void find2 (Box e){
for (Box a : newlist){
if (a.equals(e)){
System.out.println("Found");
}else {
System.out.println("Not found");
}
}
}
}
public class Box<T , D>{
private T name;
private D money;
public Box(T name, D money) {
this.name = name;
this.money = money;
}
public T getName() {
return name;
}
public D getMoney() {
return money;
}
#Override
public String toString() {
return name + " " + money;
}
}
Can someone show me how to search for an object in ArrayList.
Method find() it works perfect but in my opinion is wrong and
the reason why I am thinking like that, because I am passing as parameter a string and an integer but should be an box object or maybe I wrong?
In my second method find2() I am trying to pass as parameter an object of Box and when I am trying to search for it I got a false result =(
I am noobie I am trying to understand and to learn.
Stop using raw types!
Box is generic, so if you are not targeting older Java versions, always add generic parameters!.
The declaration of find2 should be like this:
public static void find2 (Box<String, Integer> e)
And you should check whether two boxes are equal in exactly the way you did in find. equals will not work because you did not define an equals method in Box. So:
for (Box<String, Integer> a : newlist){
if (a.getName().equals(e.getName()) &&
a.getMoney().equals(e.getMoney())){
System.out.println("Found");
}else {
System.out.println("Not found");
}
}
You should override Object.equals() on the Box class.
Try to handle null correctly too. Because 2 Box with null names and/or null money are in fact equal.
(you DON'T need to override Object.hashCode() for this, but it's a good practice to do so, just in case it is used in a hashmap or hashset or such).
The easiest way to search and find something in an arraylist is to use the .equals method combined with a for loop to iterate through your lists.
for(int i = 0; i < newList; ++i)
{
if(newlist.equals(Stringname))
{
//it matches so do something in here
}
}
what it is doing here is moving through the list 1 by 1 until it finds something that matches what you entered -> stringName

How to pass a String value to another class in Java

Currently, I am running into a problem in my Java code. I am somewhat new to Java, so I would love it if you kept that in mind.
My problem is with passing a String value from one class to another.
Main Class:
private static void charSurvey()
{
characterSurvey cSObj = new characterSurvey();
cSObj.survey();
System.out.println();
}
Second:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class characterSurvey
{
public void survey(String character)
{
Scanner s = new Scanner(System.in);
int smartChina = 0,smartAmerica = 0,dumbAmerica = 0;
String answer;
System.out.println("Are you good with girls?");
System.out.println("y/n?");
answer = s.nextLine();
if(answer.equalsIgnoreCase("y"))
{
smartChina = smartChina - 3;
smartAmerica = smartAmerica + 2;
dumbAmerica = dumbAmerica + 4;
}
//...
//ASKING SEVERAL OF ABOVE ^
List<Integer> charSelect = new ArrayList<Integer>();
charSelect.add(smartChina);
charSelect.add(smartAmerica);
charSelect.add(dumbAmerica);
Collections.sort(charSelect);
Collections.reverse(charSelect);
int outcome = charSelect.get(0);
if(smartChina == outcome)
{
character = "smartChina";
}
else if(smartAmerica == outcome)
{
character = "smartAmerica";
}
else if(dumbAmerica == outcome)
{
character = "dumbAmerica";
}
System.out.println(character);
s.close();
}
}
When I call the first class I am trying to grab the value of the second.
Disclaimer* the strings in this class were not meant to harm anyone. It was a joke between myself and my roommate from China, thanks.
It seems as if you want to obtain the character in your main class after the survey has completed, so it can be printed out in the main method.
You can simply change your void survey method to a String survey method, allowing you to return a value when that method is called:
class CharacterSurvey {
public String takeSurvey() {
//ask questions, score points
String character = null;
if(firstPerson == outcome) {
character = "First Person";
}
return character;
}
}
Now, when you call this method, you can retrieve the value returned from it:
class Main {
public static void main(String[] args) {
CharacterSurvey survey = new CharacterSurvey();
String character = survey.takeSurvey();
System.out.println(character);
}
}
There are several mistakes here.
First off, in your main class as you write you call the method survey() on the CharacterSurvey object but the survey itself the way it is implemented needs a String parameter to work
public void survey(String character)
Also this method returns void. If you want somehow to grab a string out of that method you need to declare the method as
public String survey() {}
this method returns a string now.
If i were to give a general idea, declare a String variable in the second class which will be manipulated inside the survey method and once the survey is declared as a String method return the value at the end inside the method.
By doing that you'll be able to receive the String value by calling the method on the characterSurvey object (and of course assign the value to a string variable or use it however).
Hope this helped

Categories